#include <srs_utest_protocol.hpp>

using namespace std;

#include <srs_kernel_error.hpp>
#include <srs_core_autofree.hpp>
#include <srs_rtmp_utility.hpp>
#include <srs_rtmp_msg_array.hpp>
#include <srs_rtmp_stack.hpp>
#include <srs_kernel_utility.hpp>
#include <srs_app_st.hpp>
#include <srs_rtmp_amf0.hpp>
#include <srs_rtmp_stack.hpp>

MockEmptyIO::MockEmptyIO() {
}

MockEmptyIO::~MockEmptyIO() {
}

bool MockEmptyIO::is_never_timeout(int64_t /*timeout_us*/) {
    return true;
}

int MockEmptyIO::read_fully(void* /*buf*/, size_t /*size*/, ssize_t* /*nread*/) {
    return ERROR_SUCCESS;
}

int MockEmptyIO::write(void* /*buf*/, size_t /*size*/, ssize_t* /*nwrite*/) {
    return ERROR_SUCCESS;
}

void MockEmptyIO::set_recv_timeout(int64_t /*timeout_us*/) {
}

int64_t MockEmptyIO::get_recv_timeout() {
    return -1;
}

int64_t MockEmptyIO::get_recv_bytes() {
    return -1;
}

void MockEmptyIO::set_send_timeout(int64_t /*timeout_us*/) {
}

int64_t MockEmptyIO::get_send_timeout() {
    return 0;
}

int64_t MockEmptyIO::get_send_bytes() {
    return 0;
}

int MockEmptyIO::writev(const iovec* /*iov*/, int /*iov_size*/, ssize_t* /*nwrite*/) {
    return ERROR_SUCCESS;
}

int MockEmptyIO::read(void* /*buf*/, size_t /*size*/, ssize_t* /*nread*/) {
    return ERROR_SUCCESS;
}

MockBufferIO::MockBufferIO() {
    recv_timeout = send_timeout = ST_UTIME_NO_TIMEOUT;
    recv_bytes = send_bytes = 0;
}

MockBufferIO::~MockBufferIO() {
}

bool MockBufferIO::is_never_timeout(int64_t timeout_us) {
    return (int64_t)ST_UTIME_NO_TIMEOUT == timeout_us;
}

int MockBufferIO::read_fully(void* buf, size_t size, ssize_t* nread) {
    if (in_buffer.length() < (int)size) {
        return ERROR_SOCKET_READ;
    }
    memcpy(buf, in_buffer.bytes(), size);

    recv_bytes += size;
    if (nread) {
        *nread = size;
    }
    in_buffer.erase((int)size);
    return ERROR_SUCCESS;
}

int MockBufferIO::write(void* buf, size_t size, ssize_t* nwrite) {
    send_bytes += size;
    if (nwrite) {
        *nwrite = size;
    }
    out_buffer.append((char*)buf, (int)size);
    return ERROR_SUCCESS;
}

void MockBufferIO::set_recv_timeout(int64_t timeout_us) {
    recv_timeout = timeout_us;
}

int64_t MockBufferIO::get_recv_timeout() {
    return recv_timeout;
}

int64_t MockBufferIO::get_recv_bytes() {
    return recv_bytes;
}

void MockBufferIO::set_send_timeout(int64_t timeout_us) {
    send_timeout = timeout_us;
}

int64_t MockBufferIO::get_send_timeout() {
    return send_timeout;
}

int64_t MockBufferIO::get_send_bytes() {
    return send_bytes;
}

int MockBufferIO::writev(const iovec* iov, int iov_size, ssize_t* nwrite) {
    int ret = ERROR_SUCCESS;

    ssize_t total = 0;
    for (int i = 0; i < iov_size; i++) {
        const iovec& pi = iov[i];

        ssize_t writen = 0;
        if ((ret = write(pi.iov_base, pi.iov_len, &writen)) != ERROR_SUCCESS) {
            return ret;
        }
        total += writen;
    }

    if (nwrite) {
        *nwrite = total;
    }
    return ret;
}

int MockBufferIO::read(void* buf, size_t size, ssize_t* nread) {
    if (in_buffer.length() <= 0) {
        return ERROR_SOCKET_READ;
    }

    int available = srs_min(in_buffer.length(), (int)size);
    memcpy(buf, in_buffer.bytes(), available);

    recv_bytes += available;
    if (nread) {
        *nread = available;
    }
    in_buffer.erase(available);
    return ERROR_SUCCESS;
}

#ifdef ENABLE_UTEST_PROTOCOL

#ifdef SRS_AUTO_SSL

// verify the sha256
TEST(ProtocolHandshakeTest, OpensslSha256) {
    // randome bytes to ensure the openssl sha256 is ok.
    char random_bytes[] = {
        (char)0x8b, (char)0x1c, (char)0x5c, (char)0x5c, (char)0x3b, (char)0x98, (char)0x60, (char)0x80, (char)0x3c, (char)0x97, (char)0x43, (char)0x79, (char)0x9c, (char)0x94, (char)0xec, (char)0x63, (char)0xaa, (char)0xd9, (char)0x10, (char)0xd7, (char)0x0d, (char)0x91, (char)0xfb, (char)0x1f, (char)0xbf, (char)0xe0, (char)0x29, (char)0xde, (char)0x77, (char)0x09, (char)0x21, (char)0x34, (char)0xa5, (char)0x7d, (char)0xdf, (char)0xe3, (char)0xdf, (char)0x11, (char)0xdf, (char)0xd4, (char)0x00, (char)0x57, (char)0x38, (char)0x5b, (char)0xae, (char)0x9e, (char)0x89, (char)0x35, (char)0xcf, (char)0x07, (char)0x48, (char)0xca, (char)0xc8, (char)0x25, (char)0x46, (char)0x3c,
        (char)0xb6, (char)0xdb, (char)0x9b, (char)0x39, (char)0xa6, (char)0x07, (char)0x3d, (char)0xaf, (char)0x8b, (char)0x85, (char)0xa2, (char)0x2f, (char)0x03, (char)0x64, (char)0x5e, (char)0xbd, (char)0xb4, (char)0x20, (char)0x01, (char)0x48, (char)0x2e, (char)0xc2, (char)0xe6, (char)0xcc, (char)0xce, (char)0x61, (char)0x59, (char)0x47, (char)0xf9, (char)0xdd, (char)0xc2, (char)0xa2, (char)0xfe, (char)0x64, (char)0xe6, (char)0x0b, (char)0x41, (char)0x4f, (char)0xe4, (char)0x8a, (char)0xca, (char)0xbe, (char)0x4d, (char)0x0e, (char)0x73, (char)0xba, (char)0x82, (char)0x30, (char)0x3c, (char)0x53, (char)0x36, (char)0x2e, (char)0xd3, (char)0x04, (char)0xae, (char)0x49,
        (char)0x44, (char)0x71, (char)0x6d, (char)0x4d, (char)0x5a, (char)0x14, (char)0x94, (char)0x94, (char)0x57, (char)0x78, (char)0xb9, (char)0x2a, (char)0x34, (char)0x49, (char)0xf8, (char)0xc2, (char)0xec, (char)0x4e, (char)0x29, (char)0xb6, (char)0x28, (char)0x54, (char)0x4a, (char)0x5e, (char)0x68, (char)0x06, (char)0xfe, (char)0xfc, (char)0xd5, (char)0x01, (char)0x35, (char)0x0c, (char)0x95, (char)0x6f, (char)0xe9, (char)0x77, (char)0x8a, (char)0xfc, (char)0x11, (char)0x15, (char)0x1a, (char)0xda, (char)0x6c, (char)0xf5, (char)0xba, (char)0x9e, (char)0x41, (char)0xd9, (char)0x7e, (char)0x0f, (char)0xdb, (char)0x33, (char)0xda, (char)0x35, (char)0x9d, (char)0x34,
        (char)0x67, (char)0x8f, (char)0xdf, (char)0x71, (char)0x63, (char)0x04, (char)0x9c, (char)0x54, (char)0xb6, (char)0x18, (char)0x10, (char)0x2d, (char)0x42, (char)0xd2, (char)0xf3, (char)0x14, (char)0x34, (char)0xa1, (char)0x31, (char)0x90, (char)0x48, (char)0xc9, (char)0x4b, (char)0x87, (char)0xb5, (char)0xcd, (char)0x62, (char)0x6b, (char)0x77, (char)0x18, (char)0x36, (char)0xd9, (char)0xc9, (char)0xc9, (char)0xae, (char)0x89, (char)0xfb, (char)0xed, (char)0xcd, (char)0xcb, (char)0xdb, (char)0x6e, (char)0xe3, (char)0x22, (char)0xbf, (char)0x7b, (char)0x72, (char)0x8a, (char)0xc3, (char)0x79, (char)0xd6, (char)0x1b, (char)0x6c, (char)0xe7, (char)0x9c, (char)0xc9,
        (char)0xfd, (char)0x48, (char)0xaa, (char)0xc1, (char)0xfa, (char)0xbf, (char)0x33, (char)0x87, (char)0x5c, (char)0x0d, (char)0xe5, (char)0x34, (char)0x24, (char)0x70, (char)0x14, (char)0x1e, (char)0x4a, (char)0x48, (char)0x07, (char)0x6e, (char)0xaf, (char)0xbf, (char)0xfe, (char)0x34, (char)0x1e, (char)0x1e, (char)0x19, (char)0xfc, (char)0xb5, (char)0x8a, (char)0x4f, (char)0x3c, (char)0xb4, (char)0xcf, (char)0xde, (char)0x24, (char)0x79, (char)0x65, (char)0x17, (char)0x22, (char)0x3f, (char)0xc0, (char)0x06, (char)0x76, (char)0x4e, (char)0x3c, (char)0xfb, (char)0xc3, (char)0xd0, (char)0x7f, (char)0x7b, (char)0x87, (char)0x5c, (char)0xeb, (char)0x97, (char)0x87,
    };

    char digest[SRS_OpensslHashSize];
    ASSERT_EQ(ERROR_SUCCESS,
              openssl_HMACsha256(
                  SrsGenuineFPKey, 30,
                  random_bytes, sizeof(random_bytes),
                  digest
              )
             );

    char expect_digest[] = {
        (char)0x1b, (char)0xc7, (char)0xe6, (char)0x14, (char)0xd5, (char)0x19, (char)0x8d, (char)0x99, (char)0x42, (char)0x0a, (char)0x21, (char)0x95, (char)0x26, (char)0x9a, (char)0x8a, (char)0x56,
        (char)0xb4, (char)0x82, (char)0x2a, (char)0x7f, (char)0xd3, (char)0x1d, (char)0xc3, (char)0xd8, (char)0x92, (char)0x97, (char)0xc4, (char)0x61, (char)0xb7, (char)0x4d, (char)0x5d, (char)0xd2
    };
    EXPECT_TRUE(srs_bytes_equals(digest, expect_digest, 32));
}

// verify the dh key
TEST(ProtocolHandshakeTest, DHKey) {
    _srs_internal::SrsDH dh;

    ASSERT_TRUE(ERROR_SUCCESS == dh.initialize(true));

    char pub_key1[128];
    int pkey_size = 128;
    EXPECT_TRUE(ERROR_SUCCESS == dh.copy_public_key(pub_key1, pkey_size));
    ASSERT_EQ(128, pkey_size);

    char pub_key2[128];
    EXPECT_TRUE(ERROR_SUCCESS == dh.copy_public_key(pub_key2, pkey_size));
    ASSERT_EQ(128, pkey_size);

    EXPECT_TRUE(srs_bytes_equals(pub_key1, pub_key2, 128));

    // another dh
    _srs_internal::SrsDH dh0;

    ASSERT_TRUE(ERROR_SUCCESS == dh0.initialize(true));

    EXPECT_TRUE(ERROR_SUCCESS == dh0.copy_public_key(pub_key2, pkey_size));
    ASSERT_EQ(128, pkey_size);

    EXPECT_FALSE(srs_bytes_equals(pub_key1, pub_key2, 128));
}

// flash will sendout a c0c1 encrypt by ssl.
TEST(ProtocolHandshakeTest, VerifyFPC0C1) {
    char c0c1[] = {
        (char)0x03, (char)0x00, (char)0x0f, (char)0x64, (char)0xd0, (char)0x80, (char)0x00, (char)0x07, (char)0x02, (char)0xe6, (char)0x42, (char)0xe5, (char)0x2b, (char)0xf1, (char)0x1d, (char)0x0f, (char)0x6c, (char)0xc8, (char)0x50, (char)0xf2, (char)0x06, (char)0xae, (char)0xd5, (char)0x4f, (char)0xdb, (char)0xfe, (char)0x79, (char)0xc2, (char)0xef, (char)0xf5, (char)0x01, (char)0x74, (char)0x4b, (char)0x5b, (char)0xe7, (char)0x37, (char)0xa3, (char)0xe0, (char)0xca, (char)0xe1, (char)0x97, (char)0x07, (char)0xdb, (char)0x54, (char)0x1d, (char)0x4c, (char)0x4b, (char)0xa3, (char)0xc3, (char)0x3e, (char)0xa9, (char)0xeb, (char)0xa9, (char)0x5b, (char)0x2f, (char)0x38, (char)0xa0, (char)0xa9, (char)0x98, (char)0x38, (char)0x80, (char)0x1b, (char)0xfb, (char)0xa7, (char)0x04, (char)0xff, (char)0xfd, (char)0x45, (char)0xfe, (char)0xfa, (char)0xc1, (char)0xe4, (char)0x1c, (char)0x77, (char)0x9a, (char)0x19, (char)0x39, (char)0x34, (char)0x10, (char)0x79, (char)0x12, (char)0xcf, (char)0x4e, (char)0xea, (char)0x34, (char)0x7d, (char)0x88, (char)0x47, (char)0xca, (char)0xf2, (char)0xb3, (char)0x09, (char)0x50, (char)0xbb, (char)0xe1, (char)0x20, (char)0x9b, (char)0x25, (char)0xb0, (char)0x3c, (char)0xbc, (char)0x46, (char)0x7a, (char)0x36, (char)0xb8, (char)0xc2, (char)0x4d, (char)0xd0, (char)0xf1, (char)0x20, (char)0x2a, (char)0xcc, (char)0x7a, (char)0x91, (char)0xab, (char)0x0b, (char)0xb6, (char)0xc7, (char)0x09, (char)0x0d, (char)0xf1, (char)0x34, (char)0x0c, (char)0x37, (char)0xbe, (char)0xad, (char)0x0e, (char)0xe3, (char)0x6b, (char)0x68, (char)0x0a, (char)0x7e, (char)0xd2, (char)0xd4, (char)0xc5, (char)0x3d, (char)0xdc, (char)0xac, (char)0x28, (char)0x8b, (char)0x88, (char)0xb5, (char)0x1e, (char)0xd8, (char)0x2b, (char)0x68, (char)0x72, (char)0x55, (char)0x64, (char)0xa2, (char)0xa5, (char)0x69, (char)0x0a, (char)0xdb, (char)0x26, (char)0xff, (char)0x63, (char)0x2d, (char)0xb8, (char)0xff, (char)0xb6, (char)0x33, (char)0xd3, (char)0x9d, (char)0x5c, (char)0x46, (char)0xd6, (char)0xbf, (char)0x8b, (char)0x1c, (char)0x5c, (char)0x5c, (char)0x3b, (char)0x98, (char)0x60, (char)0x80, (char)0x3c, (char)0x97, (char)0x43, (char)0x79, (char)0x9c, (char)0x94, (char)0xec, (char)0x63, (char)0xaa, (char)0xd9, (char)0x10, (char)0xd7, (char)0x0d, (char)0x91, (char)0xfb, (char)0x1f, (char)0xbf, (char)0xe0, (char)0x29, (char)0xde, (char)0x77, (char)0x09, (char)0x21, (char)0x34, (char)0xa5, (char)0x7d, (char)0xdf, (char)0xe3, (char)0xdf, (char)0x11, (char)0xdf, (char)0xd4, (char)0x00, (char)0x57, (char)0x38, (char)0x5b, (char)0xae, (char)0x9e, (char)0x89, (char)0x35, (char)0xcf, (char)0x07, (char)0x48, (char)0xca, (char)0xc8, (char)0x25, (char)0x46, (char)0x3c,
        (char)0xb6, (char)0xdb, (char)0x9b, (char)0x39, (char)0xa6, (char)0x07, (char)0x3d, (char)0xaf, (char)0x8b, (char)0x85, (char)0xa2, (char)0x2f, (char)0x03, (char)0x64, (char)0x5e, (char)0xbd, (char)0xb4, (char)0x20, (char)0x01, (char)0x48, (char)0x2e, (char)0xc2, (char)0xe6, (char)0xcc, (char)0xce, (char)0x61, (char)0x59, (char)0x47, (char)0xf9, (char)0xdd, (char)0xc2, (char)0xa2, (char)0xfe, (char)0x64, (char)0xe6, (char)0x0b, (char)0x41, (char)0x4f, (char)0xe4, (char)0x8a, (char)0xca, (char)0xbe, (char)0x4d, (char)0x0e, (char)0x73, (char)0xba, (char)0x82, (char)0x30, (char)0x3c, (char)0x53, (char)0x36, (char)0x2e, (char)0xd3, (char)0x04, (char)0xae, (char)0x49, (char)0x44, (char)0x71, (char)0x6d, (char)0x4d, (char)0x5a, (char)0x14, (char)0x94, (char)0x94, (char)0x57, (char)0x78, (char)0xb9, (char)0x2a, (char)0x34, (char)0x49, (char)0xf8, (char)0xc2, (char)0xec, (char)0x4e, (char)0x29, (char)0xb6, (char)0x28, (char)0x54, (char)0x4a, (char)0x5e, (char)0x68, (char)0x06, (char)0xfe, (char)0xfc, (char)0xd5, (char)0x01, (char)0x35, (char)0x0c, (char)0x95, (char)0x6f, (char)0xe9, (char)0x77, (char)0x8a, (char)0xfc, (char)0x11, (char)0x15, (char)0x1a, (char)0xda, (char)0x6c, (char)0xf5, (char)0xba, (char)0x9e, (char)0x41, (char)0xd9, (char)0x7e, (char)0x0f, (char)0xdb, (char)0x33, (char)0xda, (char)0x35, (char)0x9d, (char)0x34, (char)0x67, (char)0x8f, (char)0xdf, (char)0x71, (char)0x63, (char)0x04, (char)0x9c, (char)0x54, (char)0xb6, (char)0x18, (char)0x10, (char)0x2d, (char)0x42, (char)0xd2, (char)0xf3, (char)0x14, (char)0x34, (char)0xa1, (char)0x31, (char)0x90, (char)0x48, (char)0xc9, (char)0x4b, (char)0x87, (char)0xb5, (char)0xcd, (char)0x62, (char)0x6b, (char)0x77, (char)0x18, (char)0x36, (char)0xd9, (char)0xc9, (char)0xc9, (char)0xae, (char)0x89, (char)0xfb, (char)0xed, (char)0xcd, (char)0xcb, (char)0xdb, (char)0x6e, (char)0xe3, (char)0x22, (char)0xbf, (char)0x7b, (char)0x72, (char)0x8a, (char)0xc3, (char)0x79, (char)0xd6, (char)0x1b, (char)0x6c, (char)0xe7, (char)0x9c, (char)0xc9, (char)0xfd, (char)0x48, (char)0xaa, (char)0xc1, (char)0xfa, (char)0xbf, (char)0x33, (char)0x87, (char)0x5c, (char)0x0d, (char)0xe5, (char)0x34, (char)0x24, (char)0x70, (char)0x14, (char)0x1e, (char)0x4a, (char)0x48, (char)0x07, (char)0x6e, (char)0xaf, (char)0xbf, (char)0xfe, (char)0x34, (char)0x1e, (char)0x1e, (char)0x19, (char)0xfc, (char)0xb5, (char)0x8a, (char)0x4f, (char)0x3c, (char)0xb4, (char)0xcf, (char)0xde, (char)0x24, (char)0x79, (char)0x65, (char)0x17, (char)0x22, (char)0x3f, (char)0xc0, (char)0x06, (char)0x76, (char)0x4e, (char)0x3c, (char)0xfb, (char)0xc3, (char)0xd0, (char)0x7f, (char)0x7b, (char)0x87, (char)0x5c, (char)0xeb, (char)0x97, (char)0x87,
        (char)0x99, (char)0x20, (char)0x70, (char)0x7b, (char)0xf8, (char)0x97, (char)0x73, (char)0xdc, (char)0xb4, (char)0x94, (char)0x43, (char)0x27, (char)0x03, (char)0xbd, (char)0xb5, (char)0x91, (char)0xd9, (char)0x3e, (char)0x51, (char)0x1a, (char)0xd5, (char)0x60, (char)0x9c, (char)0x71, (char)0xd3, (char)0xc7, (char)0x1f, (char)0xd7, (char)0xef, (char)0x2f, (char)0xa1, (char)0xf7, (char)0xe6, (char)0xb1, (char)0x31, (char)0x9d, (char)0xec, (char)0xa3, (char)0xe1, (char)0x01, (char)0x57, (char)0xa8, (char)0x1c, (char)0x34, (char)0xf8, (char)0x82, (char)0xf5, (char)0x4d, (char)0xb8, (char)0x32, (char)0xe4, (char)0x4b, (char)0x90, (char)0x97, (char)0xcf, (char)0x8c, (char)0x2e, (char)0x89, (char)0xd0, (char)0xbc, (char)0xc0, (char)0xca, (char)0x45, (char)0x5e, (char)0x5c, (char)0x36, (char)0x47, (char)0x98, (char)0xa8, (char)0x57, (char)0xb5, (char)0x56, (char)0xc9, (char)0x11, (char)0xe4, (char)0x2f, (char)0xf0, (char)0x2b, (char)0x2c, (char)0xc1, (char)0x49, (char)0x1a, (char)0xfb, (char)0xdd, (char)0x89, (char)0x3f, (char)0x18, (char)0x98, (char)0x78, (char)0x13, (char)0x83, (char)0xf4, (char)0x30, (char)0xe2, (char)0x4e, (char)0x0e, (char)0xf4, (char)0x6c, (char)0xcb, (char)0xc6, (char)0xc7, (char)0x31, (char)0xe9, (char)0x78, (char)0x74, (char)0xfd, (char)0x53, (char)0x05, (char)0x4e, (char)0x7b, (char)0xd3, (char)0x9b, (char)0xeb, (char)0x15, (char)0xc0, (char)0x6f, (char)0xbf, (char)0xa4, (char)0x69, (char)0x7d, (char)0xd1, (char)0x53, (char)0x0f, (char)0x0b, (char)0xc1, (char)0x2b, (char)0xad, (char)0x00, (char)0x44, (char)0x10, (char)0xe2, (char)0x9f, (char)0xb9, (char)0xf3, (char)0x0c, (char)0x98, (char)0x53, (char)0xf0, (char)0x60, (char)0xcb, (char)0xee, (char)0x7e, (char)0x5c, (char)0x83, (char)0x4a, (char)0xde, (char)0xa0, (char)0x7a, (char)0xcf, (char)0x50, (char)0x2b, (char)0x84, (char)0x09, (char)0xff, (char)0x42, (char)0xe4, (char)0x80, (char)0x2a, (char)0x64, (char)0x20, (char)0x9b, (char)0xb9, (char)0xba, (char)0xd4, (char)0x54, (char)0xca, (char)0xd8, (char)0xdc, (char)0x0a, (char)0x4d, (char)0xdd, (char)0x84, (char)0x91, (char)0x5e, (char)0x16, (char)0x90, (char)0x1d, (char)0xdc, (char)0xe3, (char)0x95, (char)0x55, (char)0xac, (char)0xf2, (char)0x8c, (char)0x9a, (char)0xcc, (char)0xb2, (char)0x6d, (char)0x17, (char)0x01, (char)0xe4, (char)0x01, (char)0xc6, (char)0xba, (char)0xe4, (char)0xb8, (char)0xd5, (char)0xbd, (char)0x7b, (char)0x43, (char)0xc9, (char)0x69, (char)0x6b, (char)0x40, (char)0xf7, (char)0xdc, (char)0x65, (char)0xa4, (char)0xf7, (char)0xca, (char)0x1f, (char)0xd8, (char)0xe5, (char)0xba, (char)0x4c, (char)0xdf, (char)0xe4, (char)0x64, (char)0x9e, (char)0x7d, (char)0xbd, (char)0x54, (char)0x13, (char)0x13,
        (char)0xc6, (char)0x0c, (char)0xb8, (char)0x1d, (char)0x31, (char)0x0a, (char)0x49, (char)0xe2, (char)0x43, (char)0xb6, (char)0x95, (char)0x5f, (char)0x05, (char)0x6e, (char)0x66, (char)0xf4, (char)0x21, (char)0xa8, (char)0x65, (char)0xce, (char)0xf8, (char)0x8e, (char)0xcc, (char)0x16, (char)0x1e, (char)0xbb, (char)0xd8, (char)0x0e, (char)0xcb, (char)0xd2, (char)0x48, (char)0x37, (char)0xaf, (char)0x4e, (char)0x67, (char)0x45, (char)0xf1, (char)0x79, (char)0x69, (char)0xd2, (char)0xee, (char)0xa4, (char)0xb5, (char)0x01, (char)0xbf, (char)0x57, (char)0x0f, (char)0x68, (char)0x37, (char)0xbe, (char)0x4e, (char)0xff, (char)0xc9, (char)0xb9, (char)0x92, (char)0x23, (char)0x06, (char)0x75, (char)0xa0, (char)0x42, (char)0xe4, (char)0x0a, (char)0x30, (char)0xf0, (char)0xaf, (char)0xb0, (char)0x54, (char)0x88, (char)0x7c, (char)0xc0, (char)0xc1, (char)0x0c, (char)0x6d, (char)0x01, (char)0x36, (char)0x63, (char)0xf3, (char)0x3d, (char)0xbc, (char)0x72, (char)0xf6, (char)0x96, (char)0xc8, (char)0x87, (char)0xab, (char)0x8b, (char)0x0c, (char)0x91, (char)0x2f, (char)0x42, (char)0x2a, (char)0x11, (char)0xf6, (char)0x2d, (char)0x5e, (char)0x77, (char)0xce, (char)0x9c, (char)0xc1, (char)0x34, (char)0xe5, (char)0x2d, (char)0x9b, (char)0xd0, (char)0x37, (char)0x97, (char)0x0e, (char)0x39, (char)0xe5, (char)0xaa, (char)0xbe, (char)0x15, (char)0x3e, (char)0x6b, (char)0x1e, (char)0x73, (char)0xf6, (char)0xd7, (char)0xf4, (char)0xd6, (char)0x71, (char)0x70, (char)0xc6, (char)0xa1, (char)0xe6, (char)0x04, (char)0xd3, (char)0x7c, (char)0x2d, (char)0x1c, (char)0x98, (char)0x47, (char)0xdb, (char)0x8f, (char)0x59, (char)0x99, (char)0x2a, (char)0x57, (char)0x63, (char)0x14, (char)0xc7, (char)0x02, (char)0x42, (char)0x74, (char)0x57, (char)0x02, (char)0x22, (char)0xb2, (char)0x55, (char)0xe9, (char)0xf3, (char)0xe0, (char)0x76, (char)0x1c, (char)0x50, (char)0xbf, (char)0x43, (char)0x65, (char)0xbe, (char)0x52, (char)0xbd, (char)0x46, (char)0xf0, (char)0xfd, (char)0x5e, (char)0x25, (char)0xfe, (char)0x34, (char)0x50, (char)0x0d, (char)0x24, (char)0x7c, (char)0xfc, (char)0xfa, (char)0x82, (char)0x2f, (char)0x8c, (char)0x7d, (char)0x97, (char)0x1b, (char)0x07, (char)0x6b, (char)0x20, (char)0x6c, (char)0x9b, (char)0x7b, (char)0xae, (char)0xbf, (char)0xb3, (char)0x4f, (char)0x6e, (char)0xbb, (char)0xb6, (char)0xc4, (char)0xe9, (char)0xa5, (char)0x07, (char)0xa7, (char)0x74, (char)0x45, (char)0x16, (char)0x8a, (char)0x12, (char)0xee, (char)0x42, (char)0xc8, (char)0xea, (char)0xb5, (char)0x33, (char)0x69, (char)0xef, (char)0xff, (char)0x60, (char)0x6d, (char)0x99, (char)0xa3, (char)0x92, (char)0x5d, (char)0x0f, (char)0xbe, (char)0xb7, (char)0x4e, (char)0x1c, (char)0x85,
        (char)0xef, (char)0x9e, (char)0x1d, (char)0x38, (char)0x72, (char)0x1f, (char)0xe0, (char)0xca, (char)0xc9, (char)0x90, (char)0x85, (char)0x3f, (char)0xa6, (char)0x5d, (char)0x60, (char)0x3f, (char)0xe6, (char)0x92, (char)0x08, (char)0x3b, (char)0xd4, (char)0xc3, (char)0xa2, (char)0x7e, (char)0x7c, (char)0x35, (char)0x49, (char)0xd4, (char)0x21, (char)0x38, (char)0x8c, (char)0x2c, (char)0x49, (char)0xb3, (char)0xcb, (char)0x33, (char)0xd4, (char)0xc2, (char)0x88, (char)0xdc, (char)0x09, (char)0xb3, (char)0x8a, (char)0x13, (char)0x95, (char)0x0f, (char)0xb4, (char)0x0a, (char)0xd1, (char)0x1d, (char)0xc8, (char)0xe4, (char)0x64, (char)0xb4, (char)0x24, (char)0x51, (char)0xe1, (char)0x0a, (char)0x22, (char)0xd4, (char)0x45, (char)0x77, (char)0x91, (char)0x0a, (char)0xc6, (char)0x61, (char)0xa1, (char)0x2c, (char)0x50, (char)0x84, (char)0x1c, (char)0x0c, (char)0xbe, (char)0x05, (char)0x1c, (char)0x3b, (char)0x4f, (char)0x27, (char)0x83, (char)0x33, (char)0xba, (char)0xfb, (char)0x7f, (char)0xa0, (char)0xc6, (char)0x38, (char)0xb4, (char)0x0c, (char)0x15, (char)0x49, (char)0x8f, (char)0xfa, (char)0x17, (char)0x76, (char)0xa9, (char)0x54, (char)0xf4, (char)0x6c, (char)0x7e, (char)0x5e, (char)0x39, (char)0xb8, (char)0xa8, (char)0x78, (char)0x86, (char)0x48, (char)0xb2, (char)0x18, (char)0xf1, (char)0xde, (char)0x0d, (char)0x24, (char)0xee, (char)0x6b, (char)0x01, (char)0x7d, (char)0x60, (char)0xfa, (char)0x35, (char)0xfe, (char)0x71, (char)0x0b, (char)0xfa, (char)0x8c, (char)0x79, (char)0x6c, (char)0x0b, (char)0x25, (char)0x84, (char)0x6d, (char)0x1a, (char)0x1d, (char)0xe0, (char)0x33, (char)0xa1, (char)0xa0, (char)0x8f, (char)0x47, (char)0x08, (char)0x4b, (char)0x5c, (char)0x8c, (char)0xc6, (char)0x1e, (char)0x2a, (char)0x6d, (char)0xd8, (char)0x3e, (char)0x09, (char)0x83, (char)0x96, (char)0xe6, (char)0xbc, (char)0x14, (char)0x55, (char)0x17, (char)0xcb, (char)0x50, (char)0x44, (char)0xdb, (char)0x80, (char)0xab, (char)0xb9, (char)0xf0, (char)0x1a, (char)0x3a, (char)0x9e, (char)0x23, (char)0xd5, (char)0x46, (char)0x73, (char)0x4b, (char)0xd0, (char)0x41, (char)0x9d, (char)0x29, (char)0x03, (char)0x59, (char)0x29, (char)0xeb, (char)0x82, (char)0x71, (char)0x09, (char)0x0c, (char)0x26, (char)0x10, (char)0x0f, (char)0x59, (char)0xd4, (char)0xd7, (char)0xb4, (char)0x4d, (char)0xe5, (char)0x35, (char)0xf5, (char)0x19, (char)0xef, (char)0xc7, (char)0xe7, (char)0x43, (char)0x0a, (char)0x3e, (char)0xeb, (char)0x3d, (char)0xc5, (char)0x55, (char)0xde, (char)0x04, (char)0xe7, (char)0x88, (char)0x72, (char)0x6c, (char)0xf7, (char)0x9d, (char)0x86, (char)0xb2, (char)0x0c, (char)0x83, (char)0x55, (char)0x20, (char)0x67, (char)0xc0, (char)0xc9, (char)0x15,
        (char)0x3c, (char)0x76, (char)0x69, (char)0x80, (char)0x79, (char)0x68, (char)0x89, (char)0x16, (char)0x0a, (char)0xaf, (char)0xe4, (char)0x2c, (char)0xf0, (char)0x0e, (char)0x26, (char)0x74, (char)0x84, (char)0xfb, (char)0x27, (char)0xd4, (char)0x1c, (char)0x61, (char)0xbe, (char)0xe8, (char)0xc3, (char)0xce, (char)0x74, (char)0xd9, (char)0xf8, (char)0x5a, (char)0xa8, (char)0x63, (char)0x13, (char)0x27, (char)0xfa, (char)0xab, (char)0x93, (char)0x32, (char)0x25, (char)0x18, (char)0xb1, (char)0x78, (char)0x2f, (char)0xd3, (char)0x93, (char)0x0b, (char)0xc6, (char)0x5a, (char)0xda, (char)0xfe, (char)0xff, (char)0x7e, (char)0x38, (char)0x0c, (char)0x26, (char)0x44, (char)0x4c, (char)0x23, (char)0xe0, (char)0x8e, (char)0x64, (char)0xff, (char)0x07, (char)0xbc, (char)0x5b, (char)0x87, (char)0xd6, (char)0x3c, (char)0x8e, (char)0xe7, (char)0xd1, (char)0x78, (char)0x55, (char)0x00, (char)0x19, (char)0xbe, (char)0x98, (char)0x55, (char)0x1e, (char)0x16, (char)0xea, (char)0x63, (char)0x79, (char)0xb5, (char)0xaf, (char)0x9a, (char)0x20, (char)0x04, (char)0x8d, (char)0x3f, (char)0xdc, (char)0x15, (char)0x29, (char)0xc4, (char)0xe3, (char)0x9a, (char)0x82, (char)0x92, (char)0x85, (char)0xee, (char)0x1c, (char)0x37, (char)0xb3, (char)0xd7, (char)0xd2, (char)0x2e, (char)0x1e, (char)0xdb, (char)0x59, (char)0x87, (char)0xef, (char)0xa8, (char)0x9a, (char)0xaa, (char)0xa4, (char)0xed, (char)0x89, (char)0x33, (char)0xa8, (char)0xa7, (char)0x6c, (char)0x96, (char)0x9f, (char)0x26, (char)0xeb, (char)0xdc, (char)0x61, (char)0xc4, (char)0x8f, (char)0xd3, (char)0x2b, (char)0x81, (char)0x86, (char)0x6c, (char)0x9c, (char)0xc2, (char)0xb1, (char)0xb5, (char)0xbc, (char)0xa6, (char)0xd6, (char)0xd6, (char)0x1d, (char)0xce, (char)0x93, (char)0x78, (char)0xb3, (char)0xec, (char)0xa8, (char)0x64, (char)0x19, (char)0x13, (char)0x59, (char)0x1c, (char)0xb9, (char)0xbf, (char)0xd8, (char)0x7f, (char)0x27, (char)0x8e, (char)0x6f, (char)0x05, (char)0xd9, (char)0x1a, (char)0xa4, (char)0x1a, (char)0xc2, (char)0x46, (char)0x81, (char)0x52, (char)0xa5, (char)0xaf, (char)0x73, (char)0x35, (char)0x34, (char)0x88, (char)0x60, (char)0x46, (char)0x4d, (char)0x09, (char)0x87, (char)0xf1, (char)0x7e, (char)0x5e, (char)0xea, (char)0x32, (char)0x98, (char)0xb4, (char)0x68, (char)0x28, (char)0xff, (char)0x47, (char)0xde, (char)0x72, (char)0x9b, (char)0xc5, (char)0xfe, (char)0xb8, (char)0x93, (char)0xe8, (char)0x79, (char)0xe4, (char)0xa6, (char)0xd7, (char)0x63, (char)0x94, (char)0x29, (char)0x94, (char)0x33, (char)0x30, (char)0x61, (char)0xd4, (char)0x19, (char)0x36, (char)0x99, (char)0x94, (char)0x31, (char)0xbf, (char)0x93, (char)0x46, (char)0x04, (char)0xc0, (char)0xfe, (char)0x4d,
        (char)0x92, (char)0xb4, (char)0xbc, (char)0xb2, (char)0x14, (char)0x3f, (char)0xf7, (char)0xce, (char)0x05, (char)0xcf, (char)0xf2, (char)0x5b, (char)0x66, (char)0xcb, (char)0x67, (char)0xa9, (char)0x8f, (char)0x63, (char)0xd4, (char)0x7c, (char)0x1d, (char)0x33, (char)0x6a, (char)0x05, (char)0xfb, (char)0xf7, (char)0x11, (char)0x03, (char)0x97, (char)0xff, (char)0x02, (char)0x1b, (char)0x6f, (char)0x15, (char)0x8b, (char)0x33, (char)0xe6, (char)0xf7, (char)0x5d, (char)0x93, (char)0x21, (char)0x9d, (char)0x17, (char)0xde, (char)0x9e, (char)0x87, (char)0xdc, (char)0xcd, (char)0x9a, (char)0x6a, (char)0x30, (char)0x3e, (char)0xa9, (char)0x70, (char)0xed, (char)0x93, (char)0x1d, (char)0x43, (char)0xb5, (char)0x5d, (char)0xb0, (char)0x46, (char)0x74, (char)0x73, (char)0x3b, (char)0x25, (char)0xfa, (char)0x0e, (char)0xe3, (char)0x70, (char)0x74, (char)0x2d, (char)0x75, (char)0xd6, (char)0x14, (char)0x67, (char)0x40, (char)0x31, (char)0xf9, (char)0x2c, (char)0xf6, (char)0x38, (char)0xea, (char)0x45, (char)0x33, (char)0xc1, (char)0xb6, (char)0xd5, (char)0x93, (char)0x0f, (char)0x5c, (char)0xaf, (char)0x3a, (char)0x53, (char)0x75, (char)0xd6, (char)0xe8, (char)0x97, (char)0xa0, (char)0x51, (char)0x3f, (char)0x96, (char)0x41, (char)0x32, (char)0x0b, (char)0x59, (char)0x48, (char)0xbf, (char)0x2b, (char)0x19, (char)0x67, (char)0x98, (char)0x42, (char)0xfe, (char)0x44, (char)0x23, (char)0x84, (char)0xa9, (char)0x09, (char)0x40, (char)0x4e, (char)0x10, (char)0x25, (char)0xdf, (char)0x68, (char)0x93, (char)0x6b, (char)0x0d, (char)0xa8, (char)0x51, (char)0x47, (char)0x55, (char)0xb7, (char)0xb8, (char)0x22, (char)0xab, (char)0xa3, (char)0x3c, (char)0x78, (char)0xd6, (char)0x8b, (char)0x4f, (char)0x2a, (char)0x73, (char)0xc1, (char)0x4a, (char)0x4a, (char)0xdd, (char)0x73, (char)0xb1, (char)0xc0, (char)0x8c, (char)0x5f, (char)0xf6, (char)0xe7, (char)0xbe, (char)0x9c, (char)0x96, (char)0xd6, (char)0x37, (char)0x91, (char)0x05, (char)0x52, (char)0xd1, (char)0x2f, (char)0xa9, (char)0xdc, (char)0xca, (char)0x11, (char)0x30, (char)0x6d, (char)0x4f, (char)0xb5, (char)0x6e, (char)0x39, (char)0x24, (char)0x28, (char)0x80, (char)0x54, (char)0x28, (char)0x87, (char)0xe6, (char)0x40, (char)0xeb, (char)0xd8, (char)0x7a, (char)0x1f, (char)0x63, (char)0x56, (char)0xc1, (char)0x4d, (char)0xa0, (char)0xf8
    };
    ASSERT_EQ(1537, (int)sizeof(c0c1));

    // c0
    EXPECT_EQ(0x03, c0c1[0]);

    // c1
    c1s1 c1;

    // the schema of data must be schema0: key-digest.
    ASSERT_EQ(ERROR_SUCCESS, c1.parse(c0c1 + 1, 1536, srs_schema0));
    EXPECT_EQ((int32_t)0x000f64d0, c1.time);
    EXPECT_EQ((int32_t)0x80000702, c1.version);

    // manually validate the c1
    // @see: calc_c1_digest
    char* c1s1_joined_bytes = new char[1536 - 32];
    SrsAutoFree(char, c1s1_joined_bytes);
    ASSERT_EQ(ERROR_SUCCESS, c1.payload->copy_to(&c1, c1s1_joined_bytes, 1536 - 32, false));

    bool is_valid;
    ASSERT_EQ(ERROR_SUCCESS, c1.c1_validate_digest(is_valid));
    ASSERT_TRUE(is_valid);

    // 128bytes key
    char key[] = {
        (char)0x01, (char)0xc6, (char)0xba, (char)0xe4, (char)0xb8, (char)0xd5, (char)0xbd, (char)0x7b, (char)0x43, (char)0xc9, (char)0x69, (char)0x6b, (char)0x40, (char)0xf7, (char)0xdc, (char)0x65, (char)0xa4, (char)0xf7, (char)0xca, (char)0x1f, (char)0xd8, (char)0xe5, (char)0xba, (char)0x4c, (char)0xdf, (char)0xe4, (char)0x64, (char)0x9e, (char)0x7d, (char)0xbd, (char)0x54, (char)0x13, (char)0x13, (char)0xc6, (char)0x0c, (char)0xb8, (char)0x1d, (char)0x31, (char)0x0a, (char)0x49, (char)0xe2, (char)0x43, (char)0xb6, (char)0x95, (char)0x5f, (char)0x05, (char)0x6e, (char)0x66,
        (char)0xf4, (char)0x21, (char)0xa8, (char)0x65, (char)0xce, (char)0xf8, (char)0x8e, (char)0xcc, (char)0x16, (char)0x1e, (char)0xbb, (char)0xd8, (char)0x0e, (char)0xcb, (char)0xd2, (char)0x48, (char)0x37, (char)0xaf, (char)0x4e, (char)0x67, (char)0x45, (char)0xf1, (char)0x79, (char)0x69, (char)0xd2, (char)0xee, (char)0xa4, (char)0xb5, (char)0x01, (char)0xbf, (char)0x57, (char)0x0f, (char)0x68, (char)0x37, (char)0xbe, (char)0x4e, (char)0xff, (char)0xc9, (char)0xb9, (char)0x92, (char)0x23, (char)0x06, (char)0x75, (char)0xa0, (char)0x42, (char)0xe4, (char)0x0a, (char)0x30,
        (char)0xf0, (char)0xaf, (char)0xb0, (char)0x54, (char)0x88, (char)0x7c, (char)0xc0, (char)0xc1, (char)0x0c, (char)0x6d, (char)0x01, (char)0x36, (char)0x63, (char)0xf3, (char)0x3d, (char)0xbc, (char)0x72, (char)0xf6, (char)0x96, (char)0xc8, (char)0x87, (char)0xab, (char)0x8b, (char)0x0c, (char)0x91, (char)0x2f, (char)0x42, (char)0x2a, (char)0x11, (char)0xf6, (char)0x2d, (char)0x5e
    };
    EXPECT_TRUE(srs_bytes_equals(c1.get_key(), key, 128));

    // 32bytes digest
    char digest[] = {
        (char)0x6c, (char)0x96, (char)0x9f, (char)0x26, (char)0xeb, (char)0xdc, (char)0x61, (char)0xc4, (char)0x8f, (char)0xd3, (char)0x2b, (char)0x81, (char)0x86, (char)0x6c, (char)0x9c, (char)0xc2,
        (char)0xb1, (char)0xb5, (char)0xbc, (char)0xa6, (char)0xd6, (char)0xd6, (char)0x1d, (char)0xce, (char)0x93, (char)0x78, (char)0xb3, (char)0xec, (char)0xa8, (char)0x64, (char)0x19, (char)0x13
    };
    EXPECT_TRUE(srs_bytes_equals(c1.get_digest(), digest, 32));
}

TEST(ProtocolHandshakeTest, ComplexHandshake) {
    SrsHandshakeBytes bytes;

    if (true) {
        char c0c1[] = {
            (char)0x03, (char)0x01, (char)0x14, (char)0xf7, (char)0x4e, (char)0x80, (char)0x00, (char)0x07, (char)0x02, (char)0xac, (char)0x14, (char)0x98, (char)0x57, (char)0x0a, (char)0x07, (char)0x58, (char)0x44, (char)0x96, (char)0x47, (char)0xb5, (char)0x9a, (char)0x73, (char)0xf6, (char)0x07, (char)0x0f, (char)0x49, (char)0x0d, (char)0x72, (char)0xb8, (char)0x16, (char)0xbb, (char)0xb2, (char)0xb7, (char)0x61, (char)0x17, (char)0x79, (char)0xa0, (char)0xe9, (char)0x98, (char)0xca, (char)0xb2, (char)0x86, (char)0x64, (char)0x5f, (char)0x65, (char)0x3e, (char)0xfc, (char)0x4d, (char)0xc0, (char)0x0e, (char)0x4c, (char)0xfa, (char)0x91, (char)0xc7, (char)0x0f, (char)0x2e, (char)0x57, (char)0x31, (char)0x4b, (char)0x96, (char)0xef, (char)0xc9, (char)0x81, (char)0x02, (char)0x00, (char)0x54, (char)0x25, (char)0x2b, (char)0xb2, (char)0x0d, (char)0x7c, (char)0xee, (char)0xba, (char)0xdb, (char)0xe4, (char)0x06, (char)0x78, (char)0xcd, (char)0x70, (char)0x2c, (char)0x54, (char)0x5a, (char)0x3a, (char)0x03, (char)0x13, (char)0x2e, (char)0xe7, (char)0x4b, (char)0x87, (char)0x40, (char)0x77, (char)0x0b, (char)0x9f, (char)0xd2, (char)0xab, (char)0x32, (char)0x07, (char)0x6f, (char)0x1e, (char)0x75, (char)0x74, (char)0xe9, (char)0xc7, (char)0x44, (char)0xd9, (char)0x76, (char)0x53, (char)0xba, (char)0xe2, (char)0x52, (char)0xfa, (char)0xcc, (char)0xef, (char)0x34, (char)0xd5, (char)0x14, (char)0x61, (char)0xac, (char)0xcc, (char)0x63, (char)0xfd, (char)0x2b, (char)0x2d, (char)0xb3, (char)0xb8, (char)0xdd, (char)0x8a, (char)0x51, (char)0x9a, (char)0x2d, (char)0x0e, (char)0xfa, (char)0x84, (char)0x25, (char)0x55, (char)0xb2, (char)0xb7, (char)0x94, (char)0x54, (char)0x68, (char)0xfb, (char)0x94, (char)0xdf, (char)0xd8, (char)0xeb, (char)0x43, (char)0xd0, (char)0x11, (char)0x70, (char)0x8f, (char)0xf5, (char)0x48, (char)0xfc, (char)0x69, (char)0x4d, (char)0x5b, (char)0xc6, (char)0x53, (char)0x8a, (char)0x22, (char)0xea, (char)0x62, (char)0x84, (char)0x89, (char)0x6b, (char)0xfe, (char)0x4e, (char)0xab, (char)0x51, (char)0x98, (char)0xf4, (char)0x4f, (char)0xae, (char)0xf8, (char)0xdf, (char)0xac, (char)0x43, (char)0xed, (char)0x5a, (char)0x04, (char)0x97, (char)0xc4, (char)0xbe, (char)0x44, (char)0x5b, (char)0x99, (char)0x20, (char)0x68, (char)0x67, (char)0x0f, (char)0xe3, (char)0xfa, (char)0x4c, (char)0x9d, (char)0xe7, (char)0x0b, (char)0x3f, (char)0x80, (char)0x7c, (char)0x4c, (char)0x35, (char)0xf6, (char)0xdd, (char)0x20, (char)0x05, (char)0xfd, (char)0x0f, (char)0x39, (char)0xb7, (char)0x36, (char)0x45, (char)0x4c, (char)0xb7, (char)0x62, (char)0x92, (char)0x35, (char)0x2a, (char)0xcd, (char)0xb9, (char)0x49, (char)0xea, (char)0x12, (char)0x0b, (char)0x5f, (char)0x39, (char)0xae, (char)0x3b, (char)0x49, (char)0x29, (char)0xe6, (char)0x30, (char)0xc7, (char)0x7c, (char)0x77, (char)0xaf, (char)0x00, (char)0x43, (char)0x4d, (char)0x06, (char)0x45, (char)0x72, (char)0x73, (char)0x25, (char)0x71, (char)0x5e, (char)0x35, (char)0x04, (char)0xbd, (char)0xe9, (char)0x48, (char)0x23, (char)0x64, (char)0x4d, (char)0x15, (char)0x0b, (char)0xc5, (char)0x3f, (char)0x6e, (char)0x3a, (char)0xd5, (char)0xd5, (char)0xa6, (char)0xae, (char)0x3b, (char)0x4c, (char)0x66, (char)0x6a, (char)0x70, (char)0x8b, (char)0xf3, (char)0x6a, (char)0x43, (char)0xc4, (char)0xb9, (char)0xbd, (char)0xa0, (char)0x09, (char)0x72, (char)0xbc, (char)0xce, (char)0x7a, (char)0xea, (char)0x49, (char)0xf2, (char)0x86, (char)0xa7, (char)0xd8, (char)0x4a, (char)0x87, (char)0x28, (char)0xca, (char)0x2c, (char)0x53, (char)0xee, (char)0x96, (char)0x0b, (char)0xbe, (char)0x15, (char)0x14, (char)0xa8, (char)0x00, (char)0xca, (char)0x76, (char)0x08, (char)0x4d, (char)0x0f, (char)0xef, (char)0x78, (char)0x4b, (char)0xf6, (char)0x47, (char)0x60, (char)0xfc, (char)0x16, (char)0x00, (char)0x7c, (char)0x6b, (char)0x49, (char)0x39, (char)0x64, (char)0x36, (char)0xee, (char)0x45, (char)0x3a, (char)0x9a, (char)0xa5, (char)0xbf, (char)0xfb, (char)0x7b, (char)0xe7, (char)0xcf, (char)0x42, (char)0x82, (char)0x48, (char)0x1b, (char)0x30, (char)0xfe, (char)0x0d, (char)0xba, (char)0x10, (char)0xb8, (char)0xe1, (char)0x40, (char)0xcc, (char)0x6f, (char)0x36, (char)0x1c, (char)0x94, (char)0x5d, (char)0x50, (char)0x9e, (char)0x21, (char)0x08, (char)0xc9, (char)0xd5, (char)0xb0, (char)0x32, (char)0x51, (char)0x6a, (char)0x8f, (char)0xfa, (char)0x57, (char)0x8d, (char)0x45, (char)0xd7, (char)0xd2, (char)0xd0, (char)0xd6, (char)0x6c, (char)0x78, (char)0x95, (char)0xe9, (char)0xe1, (char)0x20, (char)0x97, (char)0x1a, (char)0x43, (char)0x40, (char)0xa3, (char)0xb5, (char)0xcc, (char)0x4b, (char)0x12, (char)0x84, (char)0x1e, (char)0x0e, (char)0xd3, (char)0x32, (char)0xca, (char)0x99, (char)0xc3, (char)0x2b, (char)0x78, (char)0x17, (char)0x24, (char)0x6b, (char)0xc7, (char)0xbc, (char)0x9d, (char)0x05, (char)0xc6, (char)0xaf, (char)0x8f, (char)0x19, (char)0x75, (char)0x3c, (char)0x08, (char)0xa6, (char)0x08, (char)0x26, (char)0x5b, (char)0xf4, (char)0x10, (char)0x40, (char)0xaa, (char)0x6a, (char)0x7e, (char)0xb9, (char)0xde, (char)0x0b, (char)0x23, (char)0x3f, (char)0x53, (char)0x5a, (char)0x20, (char)0x13, (char)0x62, (char)0xec, (char)0x53, (char)0x86, (char)0x81, (char)0x1f, (char)0xf6, (char)0x8e, (char)0xe3, (char)0xd1, (char)0xaa, (char)0xb5, (char)0x41, (char)0x87, (char)0x62, (char)0xd2, (char)0xb7, (char)0x09, (char)0x12, (char)0x71, (char)0x01, (char)0x2c, (char)0xac, (char)0x6d, (char)0x9d, (char)0x37, (char)0x46, (char)0x5b, (char)0xdc, (char)0x76, (char)0x2c, (char)0x96, (char)0x61, (char)0x88, (char)0x55, (char)0x5a, (char)0x20, (char)0xc2, (char)0x84, (char)0x95, (char)0xbd, (char)0x72, (char)0xc4, (char)0xb7, (char)0x22, (char)0xae, (char)0xeb, (char)0x49, (char)0x0e, (char)0x16, (char)0xf1, (char)0xf1, (char)0xbf, (char)0xc5, (char)0xc7, (char)0xa8, (char)0x8d, (char)0xfb, (char)0xe1, (char)0x08, (char)0x6c, (char)0xc4, (char)0x79, (char)0x81, (char)0x13, (char)0xe8, (char)0x39, (char)0xbf, (char)0x6e, (char)0x5c, (char)0xa1, (char)0x62, (char)0xfb, (char)0x32, (char)0x2a, (char)0x62, (char)0xf0, (char)0x12, (char)0x07, (char)0x31, (char)0x93, (char)0x40, (char)0xf3, (char)0xc0, (char)0xea, (char)0x1d, (char)0xd8, (char)0x65, (char)0xba, (char)0x12, (char)0xb3, (char)0x9b, (char)0xf5, (char)0x59, (char)0x9c, (char)0x4e, (char)0xf6, (char)0xb9, (char)0xf7, (char)0x85, (char)0xa1, (char)0xd9, (char)0x2f, (char)0x7c, (char)0x8b, (char)0xd0, (char)0xfc, (char)0x53, (char)0x3b, (char)0xed, (char)0x85, (char)0xa4, (char)0xd2, (char)0x5e, (char)0x69, (char)0x61, (char)0x02, (char)0x53, (char)0xb6, (char)0x19, (char)0xc7, (char)0x82, (char)0xea, (char)0x8a, (char)0x45, (char)0x01, (char)0x5d, (char)0x4b, (char)0xb3, (char)0x06, (char)0x86, (char)0x7f, (char)0x4b, (char)0x2f, (char)0xe7, (char)0xa8, (char)0xd0, (char)0x28, (char)0x62, (char)0x02, (char)0xe8, (char)0xf3, (char)0x9e, (char)0x1e, (char)0x72, (char)0x82, (char)0x07, (char)0x9f, (char)0xdd, (char)0xd2, (char)0x83, (char)0x7d, (char)0x89, (char)0x73, (char)0x1b, (char)0x6f, (char)0x35, (char)0x20, (char)0xb7, (char)0x88, (char)0x15, (char)0x92, (char)0xa7, (char)0x11, (char)0xfe, (char)0x81, (char)0x68, (char)0xed, (char)0x14, (char)0x07, (char)0xdf, (char)0x4a, (char)0x06, (char)0x9c, (char)0x5e, (char)0x7e, (char)0x34, (char)0x3a, (char)0x2a, (char)0x8a, (char)0xd3, (char)0xe8, (char)0xf8, (char)0xd4, (char)0xdb, (char)0xe3, (char)0xe9, (char)0x73, (char)0xbf, (char)0xa7, (char)0xe9, (char)0x73, (char)0x62, (char)0xf2, (char)0x9d, (char)0xc1, (char)0xf7, (char)0x51, (char)0xeb, (char)0xff, (char)0xb7, (char)0xe6, (char)0xd9, (char)0xac, (char)0x46, (char)0x06, (char)0x74, (char)0xe2, (char)0x25, (char)0x3f, (char)0x46, (char)0x43, (char)0xce, (char)0x49, (char)0x52, (char)0x25, (char)0x1b, (char)0xf9, (char)0x24, (char)0x5c, (char)0xda, (char)0xfd, (char)0x7f, (char)0xf6, (char)0xef, (char)0xb3, (char)0xd5, (char)0xe9, (char)0x6e, (char)0x35, (char)0xb8, (char)0xd1, (char)0x0e, (char)0x2c, (char)0xc1, (char)0x48, (char)0x5a, (char)0x27, (char)0x0a, (char)0x81, (char)0x01, (char)0x0f, (char)0xe4, (char)0x51, (char)0xcf, (char)0x89, (char)0x36, (char)0xd3, (char)0xe8, (char)0x5e, (char)0x05, (char)0xb9, (char)0x83, (char)0x42, (char)0xf3, (char)0xa5, (char)0x94, (char)0x67, (char)0x6d, (char)0x6a, (char)0x6e, (char)0xad, (char)0xf8, (char)0x90, (char)0xb1, (char)0x1d, (char)0x63, (char)0x18, (char)0x52, (char)0xc1, (char)0xbf, (char)0xbc, (char)0xad, (char)0xf4, (char)0xd2, (char)0xc5, (char)0xef, (char)0xca, (char)0x4c, (char)0xfe, (char)0xa1, (char)0xda, (char)0x15, (char)0x92, (char)0x4c, (char)0x42, (char)0x3d, (char)0xfc, (char)0x80, (char)0x7e, (char)0x49, (char)0x13, (char)0x4e, (char)0xf6, (char)0xe1, (char)0xee, (char)0x70, (char)0xca, (char)0xd9, (char)0x0a, (char)0xde, (char)0x9b, (char)0xea, (char)0xcd, (char)0xf9, (char)0x90, (char)0xfd, (char)0xae, (char)0x09, (char)0xce, (char)0xb6, (char)0xa0, (char)0xf7, (char)0xd1, (char)0xe6, (char)0x0c, (char)0x55, (char)0x1e, (char)0x3f, (char)0xbb, (char)0x1e, (char)0xff, (char)0x3d, (char)0xdb, (char)0xdd, (char)0x27, (char)0x80, (char)0x06, (char)0x53, (char)0x7e, (char)0x0b, (char)0x2a, (char)0x80, (char)0x24, (char)0x51, (char)0x5c, (char)0x6a, (char)0xab, (char)0x32, (char)0x5d, (char)0x37, (char)0x8a, (char)0xf4, (char)0xb7, (char)0x11, (char)0xa7, (char)0xc1, (char)0x9e, (char)0x05, (char)0x2c, (char)0x16, (char)0xc2, (char)0x08, (char)0xe2, (char)0xac, (char)0x1a, (char)0xeb, (char)0x60, (char)0xf8, (char)0xd2, (char)0xea, (char)0x39, (char)0x01, (char)0x1c, (char)0x64, (char)0xbd, (char)0x22, (char)0x80, (char)0x19, (char)0x20, (char)0xc9, (char)0x6f, (char)0xdd, (char)0x5c, (char)0x73, (char)0x8c, (char)0xa1, (char)0x53, (char)0x48, (char)0x2e, (char)0x99, (char)0x1d, (char)0xc0, (char)0x8f, (char)0x28, (char)0xf1, (char)0xe3, (char)0xc5, (char)0xc5, (char)0x65, (char)0x53, (char)0xf2, (char)0x44, (char)0x44, (char)0x24, (char)0xb9, (char)0xe2, (char)0x73, (char)0xe4, (char)0x76, (char)0x14, (char)0x56, (char)0xb8, (char)0x82, (char)0xe3, (char)0xb4, (char)0xfd, (char)0x68, (char)0x31, (char)0xed, (char)0x40, (char)0x10, (char)0x99, (char)0xd3, (char)0x3d, (char)0xe5, (char)0x6b, (char)0x14, (char)0x61, (char)0x66, (char)0x9a, (char)0xf6, (char)0x33, (char)0x98, (char)0xc5, (char)0x4d, (char)0x11, (char)0xbb, (char)0xf8, (char)0x56, (char)0xf8, (char)0x8f, (char)0xd7, (char)0xb9, (char)0xda, (char)0xa3, (char)0x56, (char)0x1a, (char)0xe0, (char)0x9e, (char)0xbe, (char)0x5f, (char)0x56, (char)0xe5, (char)0xb9, (char)0xd8, (char)0xf3, (char)0xbc, (char)0x19, (char)0xf5, (char)0xe9, (char)0x1f, (char)0xd2, (char)0xea, (char)0xf4, (char)0x5a, (char)0xde, (char)0xed, (char)0xd4, (char)0x9e, (char)0xc8, (char)0xf5, (char)0x54,
            (char)0x83, (char)0x8b, (char)0x8c, (char)0x2d, (char)0x24, (char)0x0e, (char)0x30, (char)0xb1, (char)0x84, (char)0xa2, (char)0xbe, (char)0x2c, (char)0x86, (char)0xe6, (char)0x42, (char)0x82, (char)0xaa, (char)0x37, (char)0x64, (char)0x55, (char)0x51, (char)0xbc, (char)0xde, (char)0xc0, (char)0x63, (char)0x88, (char)0xf6, (char)0x31, (char)0x71, (char)0x52, (char)0xd5, (char)0x34, (char)0x0f, (char)0x8e, (char)0xcb, (char)0x28, (char)0x65, (char)0x93, (char)0x1a, (char)0x66, (char)0x3b, (char)0x21, (char)0x00, (char)0xaa, (char)0x7a, (char)0xda, (char)0x2d, (char)0xf6, (char)0x7e, (char)0xb5, (char)0x27, (char)0x79, (char)0xf4, (char)0x50, (char)0x3b, (char)0x10, (char)0x6b, (char)0x3c, (char)0xd7, (char)0x99, (char)0x9d, (char)0xf6, (char)0xc5, (char)0x01, (char)0x91, (char)0xa0, (char)0xd5, (char)0x4f, (char)0xd3, (char)0x76, (char)0x54, (char)0xa8, (char)0x5c, (char)0x35, (char)0x1d, (char)0xe2, (char)0x35, (char)0x6a, (char)0x68, (char)0x67, (char)0x03, (char)0xc4, (char)0x1f, (char)0xe9, (char)0x60, (char)0xb8, (char)0x49, (char)0xb1, (char)0x9a, (char)0x40, (char)0xd9, (char)0x3c, (char)0x4c, (char)0x73, (char)0xaa, (char)0x88, (char)0x63, (char)0xaf, (char)0xfe, (char)0xe8, (char)0xa8, (char)0x0c, (char)0x96, (char)0xbe, (char)0xb4, (char)0x65, (char)0x7c, (char)0x27, (char)0xfb, (char)0xc1, (char)0x27, (char)0x24, (char)0x58, (char)0xab, (char)0x4b, (char)0xa0, (char)0x5a, (char)0x7d, (char)0xc7, (char)0xca, (char)0x2d, (char)0xa5, (char)0x22, (char)0xa7, (char)0xed, (char)0x26, (char)0x87, (char)0xd5, (char)0x44, (char)0x1a, (char)0xc7, (char)0xdd, (char)0xfb, (char)0x60, (char)0xfc, (char)0xe5, (char)0x50, (char)0xd9, (char)0x8d, (char)0xa7, (char)0xdb, (char)0x78, (char)0xb6, (char)0x9d, (char)0x80, (char)0x0f, (char)0xb9, (char)0x5f, (char)0xa7, (char)0x53, (char)0x92, (char)0x5d, (char)0x18, (char)0xce, (char)0x89, (char)0xc2, (char)0x69, (char)0xee, (char)0xcf, (char)0xb6, (char)0x66, (char)0xe5, (char)0x66, (char)0xd2, (char)0xe3, (char)0x35, (char)0x74, (char)0x0b, (char)0x83, (char)0xb6, (char)0xde, (char)0xf1, (char)0xfb, (char)0xb4, (char)0x1d, (char)0x4b, (char)0x94, (char)0x95, (char)0x06, (char)0x82, (char)0xe7, (char)0x1c, (char)0xf8, (char)0xc5, (char)0xe6, (char)0xd0, (char)0xf2, (char)0x17, (char)0x37, (char)0x44, (char)0xfe, (char)0x99, (char)0x43, (char)0x82, (char)0xbb, (char)0x88, (char)0xe4, (char)0x43, (char)0x67, (char)0xcc, (char)0x4d, (char)0x5f, (char)0xa6, (char)0x26, (char)0xd7, (char)0x53, (char)0xd6, (char)0x45, (char)0x96, (char)0x2b, (char)0x63, (char)0xd1, (char)0x2a, (char)0xa1, (char)0x2c, (char)0x41, (char)0x59, (char)0x8b, (char)0xb8, (char)0xc1, (char)0x89, (char)0x03, (char)0x3a, (char)0x61, (char)0x13, (char)0xc4, (char)0x2c, (char)0x37, (char)0xa5, (char)0xbf, (char)0xd7, (char)0xdb, (char)0xd8, (char)0x53, (char)0x5f, (char)0xa1, (char)0xdb, (char)0xdb, (char)0xa5, (char)0x73, (char)0xb6, (char)0xf7, (char)0x74, (char)0xa0, (char)0xf8, (char)0x93, (char)0xf5, (char)0x61, (char)0xee, (char)0x3c, (char)0xe7, (char)0x00, (char)0x01, (char)0x98, (char)0xe0, (char)0xa1, (char)0x22, (char)0xb6, (char)0x9a, (char)0x83, (char)0x44, (char)0xa1, (char)0xe6, (char)0x70, (char)0x56, (char)0x65, (char)0x92, (char)0x1e, (char)0xf0, (char)0xbc, (char)0x73, (char)0xa5, (char)0x7a, (char)0xc1, (char)0x1a, (char)0x02, (char)0xf9, (char)0xd4, (char)0xc4, (char)0x7c, (char)0x81, (char)0xda, (char)0x15, (char)0xc0, (char)0xd4, (char)0x25, (char)0xdc, (char)0x17, (char)0xa6, (char)0x0d, (char)0x90, (char)0x55, (char)0xf2, (char)0x10, (char)0xf8, (char)0xa7, (char)0x71, (char)0x9b, (char)0xed, (char)0xdf, (char)0xdf, (char)0xa1, (char)0xe4, (char)0xb9, (char)0x12, (char)0x6b, (char)0x05, (char)0x3e, (char)0x83, (char)0x99, (char)0x49, (char)0xbf, (char)0x66, (char)0xbb, (char)0xf6, (char)0x76, (char)0xd3, (char)0xa9, (char)0x24, (char)0x61, (char)0x8c, (char)0x25, (char)0x49, (char)0xd0, (char)0xf7, (char)0x83, (char)0x44, (char)0xfb, (char)0x27, (char)0xe2, (char)0x7d, (char)0x69, (char)0x6d, (char)0x34, (char)0x67, (char)0xed, (char)0x39, (char)0x89, (char)0x02, (char)0xcb, (char)0x2f, (char)0x33, (char)0x3c, (char)0xcd, (char)0x12, (char)0x42, (char)0x8f, (char)0x86, (char)0x7d, (char)0xda, (char)0x3f, (char)0xd7, (char)0x26, (char)0x62, (char)0x9c, (char)0x1f, (char)0x2e, (char)0xa8, (char)0xc3, (char)0x85, (char)0xf1, (char)0x73, (char)0xe5, (char)0x2c, (char)0x11, (char)0xde, (char)0x98, (char)0xc8, (char)0xb0, (char)0x10, (char)0x17, (char)0x55, (char)0xf5, (char)0x32, (char)0x52, (char)0x67, (char)0xca, (char)0x64, (char)0x50, (char)0x28, (char)0x9a, (char)0x24, (char)0x92, (char)0xa1, (char)0x97, (char)0x57, (char)0x81, (char)0xaf, (char)0xca, (char)0x1e, (char)0xc0, (char)0xa4, (char)0x71, (char)0x2d, (char)0x2a, (char)0xec, (char)0xc9, (char)0x23, (char)0x6a, (char)0x0c, (char)0x1d, (char)0x54, (char)0x15, (char)0x2a, (char)0x56, (char)0x42, (char)0x0a, (char)0x83, (char)0xff, (char)0x28, (char)0xba, (char)0xe7, (char)0x68, (char)0x38, (char)0xf5, (char)0x32, (char)0xa9, (char)0xb7, (char)0xe7, (char)0x70, (char)0x32, (char)0xa8, (char)0x79, (char)0x5e, (char)0x46, (char)0x1d, (char)0xec, (char)0x29, (char)0x8a, (char)0xde, (char)0x41, (char)0x94, (char)0x94, (char)0x26, (char)0x79, (char)0xc2, (char)0x52, (char)0x23, (char)0xe0, (char)0xa1, (char)0x1d, (char)0x65, (char)0x0c, (char)0xbe, (char)0x1b, (char)0x87, (char)0x2a, (char)0x21, (char)0x53, (char)0x2f, (char)0x35, (char)0x56, (char)0xe8, (char)0xd1, (char)0x7b, (char)0xb8, (char)0x23, (char)0x75, (char)0x56, (char)0xc7, (char)0x08, (char)0x9d, (char)0x13, (char)0xf0, (char)0x8f, (char)0x80, (char)0x38, (char)0xe9, (char)0x92, (char)0xf7, (char)0x16, (char)0xc2, (char)0xf3, (char)0x74, (char)0xa7, (char)0x92, (char)0xf5, (char)0x49, (char)0x7d, (char)0x09, (char)0x41, (char)0xbc, (char)0x07, (char)0x61, (char)0x1f, (char)0xe6, (char)0xa0, (char)0xd8, (char)0xa6, (char)0xe3, (char)0x72, (char)0xa4, (char)0x59, (char)0x4a, (char)0xd9, (char)0x33, (char)0x40, (char)0x80, (char)0x3a, (char)0x3a, (char)0xb3, (char)0xa0, (char)0x96, (char)0xca, (char)0x56, (char)0x98, (char)0xbd, (char)0x1f, (char)0x80, (char)0x86, (char)0x6c, (char)0xe1, (char)0x09, (char)0x64, (char)0x1b, (char)0x1a, (char)0xc9, (char)0x52, (char)0xaa, (char)0xd1, (char)0x39, (char)0xea, (char)0x4b, (char)0x6a, (char)0x3e, (char)0x4e, (char)0xa4, (char)0xea, (char)0x00, (char)0xde, (char)0x07, (char)0x0b, (char)0x23, (char)0xbc, (char)0x40, (char)0xc4, (char)0xd2, (char)0xd9, (char)0xf6, (char)0xda, (char)0x8e, (char)0x22, (char)0x36, (char)0xbe, (char)0x5e, (char)0x65, (char)0x6e, (char)0xbe, (char)0xc8, (char)0xb0, (char)0x07, (char)0xa2, (char)0x2d, (char)0xe9, (char)0x4b, (char)0x73, (char)0x54, (char)0xe6, (char)0x0a, (char)0xf2, (char)0xd3, (char)0x83, (char)0x8b, (char)0x27, (char)0x4c, (char)0xcc, (char)0x0c, (char)0x8a, (char)0xd4, (char)0x2b, (char)0xb8, (char)0x95, (char)0x2e, (char)0x42, (char)0x64, (char)0x29, (char)0xc1, (char)0xe0, (char)0x6b, (char)0x92, (char)0xab, (char)0xfe, (char)0x53, (char)0x06, (char)0x96, (char)0x4a, (char)0x8c, (char)0x5d, (char)0x7c, (char)0x51, (char)0x74, (char)0xd0, (char)0x1e, (char)0x37, (char)0x35, (char)0x9c, (char)0x1e, (char)0x69, (char)0x8f, (char)0x68, (char)0x18, (char)0xd9, (char)0xbe, (char)0xaf, (char)0x81, (char)0x9b, (char)0x7e, (char)0xd8, (char)0x71, (char)0x9d, (char)0xb6, (char)0x50, (char)0x43, (char)0x78, (char)0x85, (char)0x7d, (char)0x65, (char)0x93, (char)0x45, (char)0xb4, (char)0x02, (char)0xd0, (char)0x5c, (char)0x36, (char)0xe2, (char)0x62, (char)0x3f, (char)0x40, (char)0x33, (char)0xee, (char)0x91, (char)0xe5, (char)0x3f, (char)0x67, (char)0x39, (char)0x2f, (char)0x1b, (char)0x89, (char)0x9f, (char)0x04, (char)0x9d, (char)0x46, (char)0x3e, (char)0x70, (char)0x92, (char)0x9e, (char)0x8c, (char)0xf5
        };
        char s0s1s2[] = {
            (char)0x03, (char)0xac, (char)0x44, (char)0x29, (char)0x53, (char)0x04, (char)0x05, (char)0x00, (char)0x01, (char)0x6e, (char)0x65, (char)0x69, (char)0x2d, (char)0x69, (char)0x2d, (char)0x69, (char)0x73, (char)0x6e, (char)0x69, (char)0x73, (char)0x6c, (char)0x65, (char)0x72, (char)0x69, (char)0x72, (char)0x76, (char)0x65, (char)0x72, (char)0x69, (char)0x77, (char)0x74, (char)0x2e, (char)0x6e, (char)0x72, (char)0x76, (char)0x72, (char)0x65, (char)0x72, (char)0x70, (char)0x72, (char)0x69, (char)0x69, (char)0x70, (char)0x72, (char)0x73, (char)0x6e, (char)0x65, (char)0x72, (char)0x72, (char)0x6e, (char)0x2d, (char)0x65, (char)0x74, (char)0x72, (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x40, (char)0x69, (char)0x69, (char)0x76, (char)0x77, (char)0x2d, (char)0x73, (char)0x65, (char)0x72, (char)0x72, (char)0x76, (char)0x73, (char)0x72, (char)0x2e, (char)0x2d, (char)0x76, (char)0x65, (char)0x31, (char)0x65, (char)0x6d, (char)0x6d, (char)0x73, (char)0x69, (char)0x73, (char)0x74, (char)0x2e, (char)0x74, (char)0x72, (char)0x65, (char)0x65, (char)0x72, (char)0x65, (char)0x2d, (char)0x74, (char)0x69, (char)0x31, (char)0x65, (char)0x2d, (char)0x6f, (char)0x77, (char)0x2e, (char)0x76, (char)0x77, (char)0x2d, (char)0x77, (char)0x72, (char)0x65, (char)0x65, (char)0x31, (char)0x74, (char)0x73, (char)0x70, (char)0x74, (char)0x6e, (char)0x72, (char)0x6e, (char)0x73, (char)0x6d, (char)0x2e, (char)0x69, (char)0x72, (char)0x2d, (char)0x65, (char)0x69, (char)0x77, (char)0x69, (char)0x76, (char)0x72, (char)0x77, (char)0x72, (char)0x32, (char)0x6e, (char)0x65, (char)0x6c, (char)0x2e, (char)0x2d, (char)0x6e, (char)0x69, (char)0x6d, (char)0x6c, (char)0x73, (char)0x65, (char)0x73, (char)0x70, (char)0x2d, (char)0x65, (char)0x72, (char)0x40, (char)0x72, (char)0x74, (char)0x6e, (char)0x6e, (char)0x6d, (char)0x6f, (char)0x70, (char)0x74, (char)0x73, (char)0x2d, (char)0x63, (char)0x69, (char)0x32, (char)0x31, (char)0x2d, (char)0x40, (char)0x69, (char)0x70, (char)0x2d, (char)0x2d, (char)0x72, (char)0x69, (char)0x74, (char)0x63, (char)0x6f, (char)0x69, (char)0x69, (char)0x65, (char)0x6e, (char)0x32, (char)0x6f, (char)0x6c, (char)0x6e, (char)0x72, (char)0x73, (char)0x77, (char)0x65, (char)0x65, (char)0x72, (char)0x32, (char)0x6d, (char)0x65, (char)0x6c, (char)0x2d, (char)0x72, (char)0x6e, (char)0x65, (char)0x6d, (char)0x31, (char)0x65, (char)0x74, (char)0x2d, (char)0x6f, (char)0x72, (char)0x65, (char)0x63, (char)0x69, (char)0x40, (char)0x70, (char)0x2d, (char)0x65, (char)0x6d, (char)0x2d, (char)0x77, (char)0x63, (char)0x63, (char)0x74, (char)0x40, (char)0x36, (char)0x2d, (char)0x72, (char)0x65, (char)0x70, (char)0x2d, (char)0x6e, (char)0x69, (char)0x6d, (char)0x65, (char)0x74, (char)0x70, (char)0x76, (char)0x40, (char)0x76, (char)0x72, (char)0x72, (char)0x69, (char)0x77, (char)0x76, (char)0x69, (char)0x74, (char)0x74, (char)0x65, (char)0x31, (char)0x6d, (char)0x2e, (char)0x6f, (char)0x72, (char)0x73, (char)0x73, (char)0x6c, (char)0x40, (char)0x36, (char)0x72, (char)0x70, (char)0x72, (char)0x70, (char)0x72, (char)0x69, (char)0x32, (char)0x6c, (char)0x77, (char)0x70, (char)0x76, (char)0x65, (char)0x72, (char)0x76, (char)0x63, (char)0x65, (char)0x65, (char)0x77, (char)0x72, (char)0x6e, (char)0x2e, (char)0x76, (char)0x69, (char)0x69, (char)0x2e, (char)0x40, (char)0x72, (char)0x2e, (char)0x2e, (char)0x72, (char)0x73, (char)0x6e, (char)0x72, (char)0x72, (char)0x6e, (char)0x70, (char)0x40, (char)0x77, (char)0x65, (char)0x77, (char)0x65, (char)0x70, (char)0x63, (char)0x74, (char)0x2d, (char)0x70, (char)0x72, (char)0x2d, (char)0x74, (char)0x72, (char)0x31, (char)0x65, (char)0x6e, (char)0x2d, (char)0x76, (char)0x2d, (char)0x2d, (char)0x2d, (char)0x74, (char)0x76, (char)0x2d, (char)0x74, (char)0x65, (char)0x2e, (char)0x2d, (char)0x6c, (char)0x76, (char)0x2d, (char)0x6c, (char)0x70, (char)0x73, (char)0x6d, (char)0x65, (char)0x72, (char)0x31, (char)0x31, (char)0x36, (char)0x76, (char)0x73, (char)0x73, (char)0x6e, (char)0x2d, (char)0x6e, (char)0x73, (char)0x72, (char)0x2d, (char)0x6f, (char)0x6c, (char)0x65, (char)0x74, (char)0x77, (char)0x65, (char)0x69, (char)0x72, (char)0x69, (char)0x65, (char)0x6d, (char)0x76, (char)0x31, (char)0x65, (char)0x73, (char)0x72, (char)0x6c, (char)0x72, (char)0x77, (char)0x65, (char)0x76, (char)0x74, (char)0x72, (char)0x69, (char)0x72, (char)0x76, (char)0x32, (char)0x73, (char)0x6d, (char)0x72, (char)0x2d, (char)0x6d, (char)0x40, (char)0x69, (char)0x40, (char)0x69, (char)0x31, (char)0x69, (char)0x6f, (char)0x6e, (char)0x6d, (char)0x69, (char)0x73, (char)0x70, (char)0x72, (char)0x77, (char)0x6f, (char)0x6f, (char)0x65, (char)0x77, (char)0x76, (char)0x70, (char)0x70, (char)0x6c, (char)0x6f, (char)0x72, (char)0x65, (char)0x32, (char)0x36, (char)0x6c, (char)0x74, (char)0x6e, (char)0x72, (char)0x74, (char)0x2d, (char)0x6e, (char)0x6c, (char)0x72, (char)0x72, (char)0x2d, (char)0x74, (char)0x65, (char)0x73, (char)0x70, (char)0x65, (char)0x72, (char)0x6c, (char)0x65, (char)0x65, (char)0x2d, (char)0x6e, (char)0x70, (char)0x6e, (char)0x40, (char)0x65, (char)0x6e, (char)0x6e, (char)0x74, (char)0x65, (char)0x6e, (char)0x72, (char)0x6e, (char)0xfe, (char)0x5a, (char)0x38, (char)0x79, (char)0x81, (char)0xe8, (char)0x49, (char)0xee, (char)0x93, (char)0xbb, (char)0xa0, (char)0x59, (char)0x4a, (char)0xa0, (char)0xcc, (char)0x31, (char)0xbf, (char)0x0d, (char)0x86, (char)0xc0, (char)0x3f, (char)0xae, (char)0x2a, (char)0x16, (char)0xfa, (char)0xf0, (char)0x4e, (char)0x0f, (char)0xa3, (char)0x01, (char)0x06, (char)0xa0, (char)0x0e, (char)0xa5, (char)0x8c, (char)0xa4, (char)0xca, (char)0xd2, (char)0x01, (char)0xa5, (char)0x90, (char)0xbd, (char)0x55, (char)0xd1, (char)0x42, (char)0x2b, (char)0xd4, (char)0xb3, (char)0xbb, (char)0x06, (char)0xb1, (char)0x3a, (char)0x94, (char)0x41, (char)0x76, (char)0x1d, (char)0xa5, (char)0x23, (char)0x6e, (char)0x1e, (char)0x59, (char)0x73, (char)0x63, (char)0x34, (char)0x60, (char)0xd3, (char)0x48, (char)0xc0, (char)0x3b, (char)0xcf, (char)0xf1, (char)0xa8, (char)0x38, (char)0xd6, (char)0xf3, (char)0x5e, (char)0x6d, (char)0xcb, (char)0xea, (char)0xfc, (char)0x9c, (char)0x52, (char)0xae, (char)0x9a, (char)0x89, (char)0xdb, (char)0x24, (char)0x1b, (char)0x92, (char)0x4a, (char)0x85, (char)0x97, (char)0x3c, (char)0xd8, (char)0x4c, (char)0x31, (char)0xad, (char)0xfd, (char)0x00, (char)0xef, (char)0xc5, (char)0x17, (char)0xa5, (char)0x22, (char)0xc0, (char)0xf1, (char)0x94, (char)0x18, (char)0xec, (char)0xf6, (char)0x49, (char)0xe5, (char)0x05, (char)0x11, (char)0x12, (char)0x67, (char)0x6c, (char)0x71, (char)0xc0, (char)0x84, (char)0x6d, (char)0x50, (char)0xf8, (char)0x23, (char)0x01, (char)0x57, (char)0xc4, (char)0xfc, (char)0x73, (char)0x65, (char)0x69, (char)0x6e, (char)0x65, (char)0x72, (char)0x6d, (char)0x6f, (char)0x69, (char)0x2d, (char)0x65, (char)0x65, (char)0x69, (char)0x63, (char)0x63, (char)0x69, (char)0x2d, (char)0x72, (char)0x2d, (char)0x69, (char)0x2d, (char)0x2d, (char)0x77, (char)0x72, (char)0x76, (char)0x72, (char)0x72, (char)0x2d, (char)0x76, (char)0x70, (char)0x63, (char)0x69, (char)0x74, (char)0x73, (char)0x6d, (char)0x65, (char)0x6c, (char)0x2d, (char)0x73, (char)0x6c, (char)0x65, (char)0x6e, (char)0x73, (char)0x77, (char)0x69, (char)0x63, (char)0x69, (char)0x70, (char)0x31, (char)0x40, (char)0x72, (char)0x69, (char)0x2d, (char)0x2d, (char)0x2d, (char)0x72, (char)0x72, (char)0x6c, (char)0x72, (char)0x63, (char)0x72, (char)0x77, (char)0x6e, (char)0x6c, (char)0x2d, (char)0x72, (char)0x2e, (char)0x76, (char)0x72, (char)0x65, (char)0x6d, (char)0x76, (char)0x36, (char)0x6d, (char)0x72, (char)0x77, (char)0x72, (char)0x65, (char)0x65, (char)0x69, (char)0x72, (char)0x76, (char)0x6d, (char)0x76, (char)0x74, (char)0x76, (char)0x72, (char)0x65, (char)0x69, (char)0x72, (char)0x6e, (char)0x6d, (char)0x77, (char)0x6c, (char)0x40, (char)0x32, (char)0x70, (char)0x65, (char)0x65, (char)0x69, (char)0x72, (char)0x31, (char)0x2e, (char)0x70, (char)0x36, (char)0x31, (char)0x65, (char)0x70, (char)0x72, (char)0x72, (char)0x73, (char)0x72, (char)0x6e, (char)0x6e, (char)0x73, (char)0x32, (char)0x2d, (char)0x2d, (char)0x2d, (char)0x69, (char)0x65, (char)0x31, (char)0x74, (char)0x6e, (char)0x65, (char)0x74, (char)0x65, (char)0x76, (char)0x69, (char)0x6d, (char)0x6c, (char)0x6e, (char)0x70, (char)0x74, (char)0x73, (char)0x72, (char)0x6d, (char)0x72, (char)0x72, (char)0x69, (char)0x65, (char)0x74, (char)0x65, (char)0x65, (char)0x2d, (char)0x70, (char)0x74, (char)0x6e, (char)0x74, (char)0x65, (char)0x6f, (char)0x72, (char)0x69, (char)0x76, (char)0x40, (char)0x31, (char)0x69, (char)0x72, (char)0x6d, (char)0x6d, (char)0x77, (char)0x69, (char)0x72, (char)0x65, (char)0x6e, (char)0x40, (char)0x63, (char)0x40, (char)0x65, (char)0x65, (char)0x69, (char)0x2d, (char)0x72, (char)0x65, (char)0x40, (char)0x69, (char)0x32, (char)0x74, (char)0x73, (char)0x6e, (char)0x36, (char)0x2d, (char)0x70, (char)0x65, (char)0x6c, (char)0x70, (char)0x6e, (char)0x72, (char)0x69, (char)0x32, (char)0x65, (char)0x74, (char)0x76, (char)0x77, (char)0x73, (char)0x6f, (char)0x77, (char)0x65, (char)0x72, (char)0x2d, (char)0x6e, (char)0x73, (char)0x65, (char)0x65, (char)0x70, (char)0x65, (char)0x2d, (char)0x65, (char)0x73, (char)0x2d, (char)0x65, (char)0x2e, (char)0x73, (char)0x69, (char)0x67, (char)0x45, (char)0x8b, (char)0x6b, (char)0x3b, (char)0xc9, (char)0x5f, (char)0x09, (char)0x65, (char)0x65, (char)0x72, (char)0x6c, (char)0x73, (char)0x6d, (char)0x70, (char)0x70, (char)0x73, (char)0x63, (char)0x70, (char)0x40, (char)0x72, (char)0x76, (char)0x65, (char)0x6e, (char)0x6f, (char)0x6c, (char)0x69, (char)0x2e, (char)0x72, (char)0x73, (char)0x76, (char)0x69, (char)0x77, (char)0x72, (char)0x2d, (char)0x69, (char)0x6e, (char)0x69, (char)0x65, (char)0x77, (char)0x73, (char)0x69, (char)0x70, (char)0x77, (char)0x63, (char)0x65, (char)0x74, (char)0x72, (char)0x73, (char)0x31, (char)0x65, (char)0x65, (char)0x72, (char)0x76, (char)0x69, (char)0x65, (char)0x77, (char)0x6d, (char)0x65, (char)0x36, (char)0x6e, (char)0x6e, (char)0x69, (char)0x6d, (char)0x6e, (char)0x70, (char)0x77, (char)0x72, (char)0x65, (char)0x31, (char)0x65, (char)0x6e, (char)0x6e, (char)0x65, (char)0x2d, (char)0x65, (char)0x65, (char)0x2e, (char)0x77, (char)0x6e, (char)0x6f, (char)0x2d, (char)0x76, (char)0x65, (char)0x72, (char)0x6c, (char)0x31, (char)0x76, (char)0x65, (char)0x72, (char)0x2d, (char)0x36, (char)0x6c, (char)0x70, (char)0x6f, (char)0x65, (char)0x72, (char)0x73, (char)0x63, (char)0x72, (char)0x77, (char)0x73, (char)0x72, (char)0x65, (char)0x65, (char)0x65, (char)0x6c, (char)0x76, (char)0x72, (char)0x65, (char)0x6e, (char)0x65, (char)0x2e, (char)0x6f, (char)0x2d, (char)0x72, (char)0x70, (char)0x65, (char)0x74, (char)0x72,
            (char)0x77, (char)0x69, (char)0x69, (char)0x72, (char)0x65, (char)0x77, (char)0x6c, (char)0x72, (char)0x2d, (char)0x69, (char)0x72, (char)0x31, (char)0x6e, (char)0x65, (char)0x70, (char)0x72, (char)0x74, (char)0x76, (char)0x6c, (char)0x2e, (char)0x72, (char)0x65, (char)0x72, (char)0x6c, (char)0x73, (char)0x6c, (char)0x2e, (char)0x2e, (char)0x72, (char)0x2d, (char)0x6e, (char)0x63, (char)0x32, (char)0x2e, (char)0x65, (char)0x2d, (char)0x65, (char)0x69, (char)0x2d, (char)0x65, (char)0x70, (char)0x6e, (char)0x72, (char)0x72, (char)0x32, (char)0x2e, (char)0x73, (char)0x70, (char)0x77, (char)0x65, (char)0x73, (char)0x77, (char)0x73, (char)0x40, (char)0x40, (char)0x73, (char)0x63, (char)0x2e, (char)0x65, (char)0x76, (char)0x70, (char)0x65, (char)0x69, (char)0x65, (char)0x70, (char)0x73, (char)0x40, (char)0x65, (char)0x73, (char)0x2d, (char)0x2d, (char)0x2e, (char)0x2e, (char)0x73, (char)0x65, (char)0x6f, (char)0x65, (char)0x65, (char)0x6d, (char)0x76, (char)0x70, (char)0x6d, (char)0x69, (char)0x70, (char)0x70, (char)0x69, (char)0x2e, (char)0x76, (char)0x6e, (char)0x72, (char)0x72, (char)0x72, (char)0x6d, (char)0x73, (char)0x6f, (char)0x73, (char)0x72, (char)0x72, (char)0x72, (char)0x77, (char)0x70, (char)0x65, (char)0x69, (char)0x72, (char)0x73, (char)0x6e, (char)0x69, (char)0x65, (char)0x65, (char)0x74, (char)0x65, (char)0x69, (char)0x40, (char)0x63, (char)0x69, (char)0x70, (char)0x6c, (char)0x6e, (char)0x2d, (char)0x65, (char)0x69, (char)0x72, (char)0x63, (char)0x6c, (char)0x72, (char)0x2e, (char)0x36, (char)0x69, (char)0x72, (char)0x6c, (char)0x6c, (char)0x2d, (char)0x6f, (char)0x76, (char)0x69, (char)0x6f, (char)0x2d, (char)0x6d, (char)0x6c, (char)0x72, (char)0x72, (char)0x2e, (char)0x70, (char)0x73, (char)0x6d, (char)0x6f, (char)0x2e, (char)0x6e, (char)0x69, (char)0x65, (char)0x65, (char)0x2d, (char)0x6d, (char)0x76, (char)0x6e, (char)0x69, (char)0x73, (char)0x73, (char)0x73, (char)0x74, (char)0x63, (char)0x65, (char)0x76, (char)0x2e, (char)0x77, (char)0x2d, (char)0x36, (char)0x73, (char)0x69, (char)0x2d, (char)0x72, (char)0x72, (char)0x6c, (char)0x36, (char)0x74, (char)0x72, (char)0x6d, (char)0x65, (char)0x2d, (char)0x65, (char)0x2e, (char)0x6d, (char)0x31, (char)0x72, (char)0x6f, (char)0x74, (char)0x76, (char)0x31, (char)0x65, (char)0x6d, (char)0x69, (char)0x72, (char)0x69, (char)0x69, (char)0x2d, (char)0x72, (char)0x73, (char)0x72, (char)0x72, (char)0x76, (char)0x31, (char)0x6e, (char)0x2d, (char)0x69, (char)0x6e, (char)0x77, (char)0x70, (char)0x69, (char)0x72, (char)0x6e, (char)0x76, (char)0x74, (char)0x6f, (char)0x65, (char)0x63, (char)0x6f, (char)0x73, (char)0x65, (char)0x73, (char)0x72, (char)0x69, (char)0x69, (char)0x40, (char)0x6e, (char)0x65, (char)0x65, (char)0x65, (char)0x65, (char)0x77, (char)0x70, (char)0x70, (char)0x6e, (char)0x72, (char)0x6e, (char)0x65, (char)0x72, (char)0x32, (char)0x65, (char)0x2d, (char)0x77, (char)0x69, (char)0x6e, (char)0x70, (char)0x69, (char)0x6f, (char)0x76, (char)0x77, (char)0x72, (char)0x74, (char)0x77, (char)0x6e, (char)0x72, (char)0xfe, (char)0x98, (char)0xf3, (char)0xb4, (char)0xff, (char)0x3f, (char)0x2e, (char)0xdb, (char)0x59, (char)0xbd, (char)0x32, (char)0x02, (char)0x6a, (char)0x44, (char)0x03, (char)0x67, (char)0x9e, (char)0xe1, (char)0x98, (char)0x97, (char)0xed, (char)0x67, (char)0x6d, (char)0xb0, (char)0x8f, (char)0xa9, (char)0xb6, (char)0xf8, (char)0x4d, (char)0x92, (char)0x35, (char)0x19, (char)0x72, (char)0x72, (char)0x65, (char)0x74, (char)0x73, (char)0x6e, (char)0x65, (char)0x65, (char)0x69, (char)0x36, (char)0x72, (char)0x73, (char)0x2d, (char)0x70, (char)0x2d, (char)0x2d, (char)0x69, (char)0x6e, (char)0x72, (char)0x65, (char)0x32, (char)0x72, (char)0x77, (char)0x72, (char)0x73, (char)0x77, (char)0x73, (char)0x70, (char)0x2d, (char)0x2d, (char)0x69, (char)0x6c, (char)0x70, (char)0x74, (char)0x65, (char)0x69, (char)0x72, (char)0x74, (char)0x6e, (char)0x76, (char)0x65, (char)0x76, (char)0x76, (char)0x69, (char)0x69, (char)0x65, (char)0x70, (char)0x6e, (char)0x73, (char)0x6e, (char)0x36, (char)0x76, (char)0x70, (char)0x76, (char)0x6c, (char)0x6c, (char)0x70, (char)0x6e, (char)0x6e, (char)0x74, (char)0x2e, (char)0x6f, (char)0x32, (char)0x74, (char)0x76, (char)0x74, (char)0x40, (char)0x72, (char)0x6e, (char)0x72, (char)0x74, (char)0x74, (char)0x2d, (char)0x6f, (char)0x72, (char)0x73, (char)0x32, (char)0x72, (char)0x32, (char)0x72, (char)0x70, (char)0x65, (char)0x65, (char)0x6e, (char)0x72, (char)0x70, (char)0x73, (char)0x72, (char)0x69, (char)0x74, (char)0x74, (char)0x6e, (char)0x72, (char)0x6c, (char)0x31, (char)0x74, (char)0x77, (char)0x31, (char)0x63, (char)0x63, (char)0x74, (char)0x69, (char)0x72, (char)0x69, (char)0x72, (char)0x70, (char)0x31, (char)0x74, (char)0x72, (char)0x76, (char)0x65, (char)0x72, (char)0x65, (char)0x6c, (char)0x76, (char)0x6d, (char)0x72, (char)0x6c, (char)0x69, (char)0x72, (char)0x65, (char)0x76, (char)0x69, (char)0x6f, (char)0x69, (char)0x6c, (char)0x74, (char)0x6e, (char)0x65, (char)0x69, (char)0x77, (char)0x73, (char)0x70, (char)0x69, (char)0x72, (char)0x2d, (char)0x65, (char)0x74, (char)0x2e, (char)0x65, (char)0x65, (char)0x6d, (char)0x72, (char)0x31, (char)0x2d, (char)0x72, (char)0x36, (char)0x65, (char)0x2d, (char)0x69, (char)0x6d, (char)0x36, (char)0x6e, (char)0x72, (char)0x6d, (char)0x6c, (char)0x72, (char)0x72, (char)0x65, (char)0x65, (char)0x6e, (char)0x31, (char)0x6e, (char)0x40, (char)0x72, (char)0x40, (char)0x6f, (char)0x73, (char)0x6d, (char)0x36, (char)0x2e, (char)0x72, (char)0x65, (char)0x36, (char)0x74, (char)0x77, (char)0x65, (char)0x65, (char)0x73, (char)0x36, (char)0x76, (char)0x6c, (char)0x6f, (char)0x2d, (char)0x36, (char)0x6d, (char)0x36, (char)0x70, (char)0x32, (char)0x74, (char)0x6d, (char)0x65, (char)0x6d, (char)0x69, (char)0x65, (char)0x65, (char)0x69, (char)0x76, (char)0x69, (char)0x74, (char)0x2d, (char)0x63, (char)0x2d, (char)0x6e, (char)0x32, (char)0x72, (char)0x63, (char)0x2d, (char)0x77, (char)0x72, (char)0x74, (char)0x72, (char)0x70, (char)0x6e, (char)0x76, (char)0x6f, (char)0x72, (char)0x40, (char)0x65, (char)0x65, (char)0x6d, (char)0x77, (char)0x2d, (char)0x2d, (char)0x74, (char)0x6e, (char)0x73, (char)0x76, (char)0x65, (char)0x69, (char)0x69, (char)0x72, (char)0x6f, (char)0x65, (char)0x70, (char)0x69, (char)0x6d, (char)0x76, (char)0x69, (char)0x65, (char)0x72, (char)0x2d, (char)0x74, (char)0x2d, (char)0x69, (char)0x65, (char)0x72, (char)0x69, (char)0x6f, (char)0x72, (char)0x72, (char)0x69, (char)0x76, (char)0x72, (char)0x77, (char)0x69, (char)0x2e, (char)0x77, (char)0x69, (char)0x70, (char)0x69, (char)0x6d, (char)0x36, (char)0x72, (char)0x76, (char)0x65, (char)0x76, (char)0x73, (char)0x6e, (char)0x72, (char)0x65, (char)0x2e, (char)0x76, (char)0x2d, (char)0x76, (char)0x6f, (char)0x2d, (char)0x65, (char)0x73, (char)0x72, (char)0x74, (char)0x36, (char)0x2d, (char)0x6f, (char)0x70, (char)0x73, (char)0x74, (char)0x74, (char)0x77, (char)0x6c, (char)0x2d, (char)0x65, (char)0x72, (char)0x6e, (char)0x65, (char)0x6c, (char)0x72, (char)0x32, (char)0x2d, (char)0x72, (char)0x69, (char)0x6d, (char)0x6e, (char)0x72, (char)0x6c, (char)0x6f, (char)0x65, (char)0x36, (char)0x31, (char)0x65, (char)0x65, (char)0x69, (char)0x73, (char)0x31, (char)0x74, (char)0x69, (char)0x69, (char)0x65, (char)0x40, (char)0x69, (char)0x6e, (char)0x2d, (char)0x63, (char)0x40, (char)0x31, (char)0x70, (char)0x65, (char)0x6e, (char)0x2d, (char)0x69, (char)0x72, (char)0x65, (char)0x65, (char)0x76, (char)0x65, (char)0x70, (char)0x72, (char)0x6c, (char)0x2d, (char)0x6e, (char)0x73, (char)0x69, (char)0x65, (char)0x65, (char)0x6e, (char)0x2e, (char)0x63, (char)0x6c, (char)0x72, (char)0x65, (char)0x2d, (char)0x2e, (char)0x6d, (char)0x72, (char)0x76, (char)0x70, (char)0x69, (char)0x6d, (char)0x40, (char)0x32, (char)0x77, (char)0x72, (char)0x6e, (char)0x72, (char)0x6c, (char)0x36, (char)0x72, (char)0x31, (char)0x2d, (char)0x73, (char)0x74, (char)0x2d, (char)0x69, (char)0x63, (char)0x40, (char)0x70, (char)0x32, (char)0x65, (char)0x31, (char)0x69, (char)0x69, (char)0x65, (char)0x72, (char)0x63, (char)0x74, (char)0x72, (char)0x74, (char)0x77, (char)0x6e, (char)0x69, (char)0x72, (char)0x65, (char)0x76, (char)0x65, (char)0x77, (char)0x69, (char)0x69, (char)0x73, (char)0x6e, (char)0x77, (char)0x77, (char)0x73, (char)0x6f, (char)0x69, (char)0x70, (char)0x73, (char)0x2d, (char)0x65, (char)0x65, (char)0x73, (char)0x65, (char)0x77, (char)0x2d, (char)0x73, (char)0x72, (char)0x6d, (char)0x65, (char)0x32, (char)0x6e, (char)0x73, (char)0x36, (char)0x65, (char)0x72, (char)0x77, (char)0x70, (char)0x65, (char)0x69, (char)0x2d, (char)0x2d, (char)0x74, (char)0x6f, (char)0x6f, (char)0x36, (char)0x63, (char)0x74, (char)0x72, (char)0x63, (char)0x77, (char)0x69, (char)0x2e, (char)0x31, (char)0x6c, (char)0x65, (char)0x77, (char)0x72, (char)0x65, (char)0x76, (char)0x74, (char)0x2d, (char)0x77, (char)0x2e, (char)0x76, (char)0x72, (char)0x6e, (char)0x36, (char)0x70, (char)0x69, (char)0x2e, (char)0x6e, (char)0x72, (char)0x77, (char)0x69, (char)0x65, (char)0x74, (char)0x2d, (char)0x6e, (char)0x63, (char)0x6e, (char)0x70, (char)0x2d, (char)0x6e, (char)0x2e, (char)0x6d, (char)0x69, (char)0x65, (char)0x63, (char)0x65, (char)0x2d, (char)0x76, (char)0x70, (char)0x73, (char)0x31, (char)0x73, (char)0x2d, (char)0x76, (char)0x6e, (char)0x6e, (char)0x6c, (char)0x2d, (char)0x6c, (char)0x2d, (char)0x65, (char)0x6e, (char)0x73, (char)0x6c, (char)0x65, (char)0x74, (char)0x70, (char)0x65, (char)0x2d, (char)0x6e, (char)0x77, (char)0x76, (char)0x40, (char)0x69, (char)0x40, (char)0x63, (char)0x6f, (char)0x72, (char)0x32, (char)0x6d, (char)0x31, (char)0x72, (char)0x36, (char)0x69, (char)0x73, (char)0x72, (char)0x70, (char)0x65, (char)0x2d, (char)0x6c, (char)0x2e, (char)0x72, (char)0x74, (char)0x74, (char)0x65, (char)0x69, (char)0x6f, (char)0x69, (char)0x2d, (char)0x2d, (char)0x65, (char)0x6f, (char)0x65, (char)0x74, (char)0x72, (char)0x69, (char)0x76, (char)0x72, (char)0x72, (char)0x65, (char)0x69, (char)0x76, (char)0x69, (char)0x69, (char)0x6e, (char)0x31, (char)0x65, (char)0x76, (char)0x72, (char)0x73, (char)0x77, (char)0x72, (char)0x2d, (char)0x69, (char)0x65, (char)0x69, (char)0x70, (char)0x65, (char)0x6e, (char)0x6e, (char)0x65, (char)0x65, (char)0x6e, (char)0x2d, (char)0x72, (char)0x76, (char)0x72, (char)0x6c, (char)0x2e, (char)0x70, (char)0x76, (char)0x6e, (char)0x69, (char)0x72, (char)0x70, (char)0x73, (char)0x2d, (char)0x69, (char)0x74, (char)0x76, (char)0x72, (char)0x70, (char)0x65, (char)0x63, (char)0x72, (char)0x70, (char)0x6e, (char)0x36, (char)0x6c, (char)0x74, (char)0x72, (char)0x72, (char)0x72, (char)0x73, (char)0x65, (char)0x40, (char)0x63, (char)0x6d, (char)0x63, (char)0x32, (char)0x65, (char)0x32, (char)0x69, (char)0x6e,
            (char)0x77, (char)0x65, (char)0x74, (char)0x72, (char)0x77, (char)0x40, (char)0x69, (char)0x65, (char)0x70, (char)0x31, (char)0x36, (char)0x72, (char)0x73, (char)0x2d, (char)0x72, (char)0x72, (char)0x32, (char)0x72, (char)0x6c, (char)0x77, (char)0x6e, (char)0x6f, (char)0x77, (char)0x6c, (char)0x74, (char)0x72, (char)0x2d, (char)0x6e, (char)0x65, (char)0x70, (char)0x6c, (char)0x72, (char)0x6f, (char)0x69, (char)0x2d, (char)0x2d, (char)0x69, (char)0x36, (char)0x69, (char)0x69, (char)0x76, (char)0x69, (char)0x69, (char)0x6d, (char)0x72, (char)0x73, (char)0x6f, (char)0x6d, (char)0x74, (char)0x70, (char)0x76, (char)0x6d, (char)0x6d, (char)0x69, (char)0x72, (char)0x70, (char)0x70, (char)0x2d, (char)0x31, (char)0x63, (char)0x6c, (char)0x65, (char)0x65, (char)0x6e, (char)0x2d, (char)0x77, (char)0x74, (char)0x73, (char)0x6c, (char)0x72, (char)0x6e, (char)0x65, (char)0x65, (char)0x2d, (char)0x6c, (char)0x69, (char)0x2d, (char)0x6e, (char)0x74, (char)0x70, (char)0x72, (char)0x77, (char)0x77, (char)0x65, (char)0x65, (char)0x65, (char)0x2d, (char)0x76, (char)0x6e, (char)0x72, (char)0x69, (char)0x69, (char)0x73, (char)0x65, (char)0x74, (char)0x73, (char)0x76, (char)0x72, (char)0x72, (char)0x72, (char)0x69, (char)0x72, (char)0x73, (char)0x72, (char)0x6f, (char)0x2e, (char)0x77, (char)0x2d, (char)0x2d, (char)0x6c, (char)0x6e, (char)0x65, (char)0x65, (char)0x6d, (char)0x73, (char)0x2e, (char)0x72, (char)0x65, (char)0x73, (char)0x40, (char)0x69, (char)0x32, (char)0x69, (char)0x32, (char)0x6e, (char)0x65, (char)0x32, (char)0x65, (char)0x74, (char)0x6d, (char)0x65, (char)0x74, (char)0x36, (char)0x6e, (char)0x72, (char)0x32, (char)0x6e, (char)0x65, (char)0x69, (char)0x32, (char)0x6f, (char)0x70, (char)0x72, (char)0x72, (char)0x65, (char)0x72, (char)0x72, (char)0x69, (char)0x6e, (char)0x6d, (char)0x69, (char)0x70, (char)0x6c, (char)0x6c, (char)0x65, (char)0x31, (char)0x72, (char)0x72, (char)0x73, (char)0x72, (char)0x70, (char)0x73, (char)0x72, (char)0x65, (char)0x65, (char)0x6e, (char)0x76, (char)0x69, (char)0x6d, (char)0x65, (char)0x6c, (char)0x65, (char)0x31, (char)0x74, (char)0x74, (char)0x72, (char)0x63, (char)0x2e, (char)0x69, (char)0x65, (char)0x2d, (char)0x6d, (char)0x72, (char)0x70, (char)0x6e, (char)0x6c, (char)0x65, (char)0x31, (char)0x73, (char)0x73, (char)0x40, (char)0x74, (char)0x72, (char)0x73, (char)0x2e, (char)0x74, (char)0x6e, (char)0x77, (char)0x6c, (char)0x6f, (char)0x70, (char)0x77, (char)0x76, (char)0x73, (char)0x72, (char)0x69, (char)0x77, (char)0x69, (char)0x6e, (char)0x69, (char)0x2d, (char)0x72, (char)0x70, (char)0x70, (char)0x73, (char)0x2e, (char)0x76, (char)0x73, (char)0x65, (char)0x72, (char)0x72, (char)0x74, (char)0x2d, (char)0x72, (char)0x65, (char)0x76, (char)0x69, (char)0x77, (char)0x72, (char)0x65, (char)0x2d, (char)0x72, (char)0x69, (char)0x36, (char)0x77, (char)0x77, (char)0x77, (char)0x40, (char)0x2d, (char)0x6d, (char)0x69, (char)0x74, (char)0x72, (char)0x2d, (char)0x32, (char)0x6f, (char)0x76, (char)0x72, (char)0x2d, (char)0x2d, (char)0x65, (char)0x2e, (char)0x2e, (char)0x72, (char)0x6e, (char)0x32, (char)0x74, (char)0x6c, (char)0x6e, (char)0x6c, (char)0x2e, (char)0x6d, (char)0x2d, (char)0x6f, (char)0x65, (char)0x72, (char)0x2d, (char)0x6e, (char)0x65, (char)0x65, (char)0x69, (char)0x40, (char)0x69, (char)0x77, (char)0x65, (char)0x6c, (char)0x2d, (char)0x69, (char)0x69, (char)0x65, (char)0x72, (char)0x72, (char)0x32, (char)0x40, (char)0x73, (char)0x65, (char)0x36, (char)0x76, (char)0x73, (char)0x72, (char)0x69, (char)0x63, (char)0x77, (char)0x72, (char)0x6c, (char)0x72, (char)0x6e, (char)0x74, (char)0x2d, (char)0x65, (char)0x69, (char)0x72, (char)0x70, (char)0x6d, (char)0x65, (char)0x6c, (char)0x73, (char)0x65, (char)0x6c, (char)0x32, (char)0x2d, (char)0x73, (char)0x70, (char)0x2d, (char)0x31, (char)0x72, (char)0x74, (char)0x2e, (char)0x65, (char)0x74, (char)0x72, (char)0x74, (char)0x72, (char)0x70, (char)0x69, (char)0x40, (char)0x36, (char)0x2d, (char)0x74, (char)0x72, (char)0x6c, (char)0x2d, (char)0x6e, (char)0x72, (char)0x6e, (char)0x6d, (char)0x63, (char)0x76, (char)0x74, (char)0x6d, (char)0x70, (char)0x32, (char)0x70, (char)0x69, (char)0x69, (char)0x2d, (char)0x73, (char)0x72, (char)0x74, (char)0x65, (char)0x74, (char)0x74, (char)0x70, (char)0x2d, (char)0x31, (char)0x6c, (char)0x77, (char)0x65, (char)0x72, (char)0x70, (char)0x73, (char)0x36, (char)0x6c, (char)0x72, (char)0x72, (char)0x65, (char)0x65, (char)0x76, (char)0x69, (char)0x2e, (char)0x6e, (char)0x72, (char)0x72, (char)0x36, (char)0x65, (char)0x69, (char)0x72, (char)0x69, (char)0x40, (char)0x6c, (char)0x74, (char)0x6c, (char)0x72, (char)0x2d, (char)0x70, (char)0x74, (char)0x76, (char)0x74, (char)0x6f, (char)0x72, (char)0x31, (char)0x73, (char)0x70, (char)0x65, (char)0x74, (char)0x69, (char)0x6e, (char)0x69, (char)0x6c, (char)0x70, (char)0x72, (char)0x65, (char)0x70, (char)0x72, (char)0x73, (char)0x69, (char)0x2d, (char)0x6d, (char)0x63, (char)0x2d, (char)0x72, (char)0x2d, (char)0x36, (char)0x73, (char)0x6e, (char)0x2d, (char)0x6d, (char)0x69, (char)0x76, (char)0x76, (char)0x6d, (char)0x74, (char)0x72, (char)0x77, (char)0x74, (char)0x2e, (char)0x6d, (char)0x65, (char)0x2d, (char)0x65, (char)0x6d, (char)0x2e, (char)0x6c, (char)0x73, (char)0x6e, (char)0x6f, (char)0x76, (char)0x31, (char)0x74, (char)0x65, (char)0x65, (char)0x31, (char)0x69, (char)0x65, (char)0x32, (char)0x2d, (char)0x74, (char)0x2d, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x70, (char)0x65, (char)0x6e, (char)0x2d, (char)0x69, (char)0x32, (char)0x72, (char)0x73, (char)0x74, (char)0x65, (char)0x65, (char)0x69, (char)0x73, (char)0x77, (char)0x77, (char)0x2e, (char)0x6e, (char)0x72, (char)0x65, (char)0x70, (char)0x76, (char)0x40, (char)0x77, (char)0x65, (char)0x2d, (char)0x70, (char)0x36, (char)0x2d, (char)0x74, (char)0x65, (char)0x2d, (char)0x69, (char)0x74, (char)0x76, (char)0x69, (char)0x6e, (char)0x65, (char)0x2d, (char)0x65, (char)0x73, (char)0x31, (char)0x36, (char)0x69, (char)0x31, (char)0x74, (char)0x76, (char)0x65, (char)0x77, (char)0x6c, (char)0x6e, (char)0x6c, (char)0x32, (char)0x6e, (char)0x70, (char)0x73, (char)0x69, (char)0x69, (char)0x65, (char)0x72, (char)0x2d, (char)0x6e, (char)0x2d, (char)0x65, (char)0x65, (char)0x6c, (char)0x32, (char)0x77, (char)0x72, (char)0x69, (char)0x70, (char)0x76, (char)0x32, (char)0x65, (char)0x6c, (char)0x36, (char)0x65, (char)0x69, (char)0x31, (char)0x6e, (char)0x72, (char)0x6c, (char)0x6d, (char)0x65, (char)0x65, (char)0x77, (char)0x6e, (char)0x2d, (char)0x32, (char)0x77, (char)0x69, (char)0x65, (char)0x6d, (char)0x74, (char)0x77, (char)0x40, (char)0x65, (char)0x6e, (char)0x77, (char)0x73, (char)0x65, (char)0x72, (char)0x6c, (char)0x40, (char)0x65, (char)0x65, (char)0x72, (char)0x72, (char)0x74, (char)0x6e, (char)0x6c, (char)0x6d, (char)0x73, (char)0x69, (char)0x76, (char)0x72, (char)0x31, (char)0x2d, (char)0x65, (char)0x36, (char)0x72, (char)0x2d, (char)0x70, (char)0x69, (char)0x6e, (char)0x63, (char)0x31, (char)0x2d, (char)0x69, (char)0x6e, (char)0x65, (char)0x2d, (char)0x65, (char)0x2e, (char)0x77, (char)0x2d, (char)0x72, (char)0x76, (char)0x63, (char)0x69, (char)0x2d, (char)0x6d, (char)0x70, (char)0x2d, (char)0x6c, (char)0x69, (char)0x63, (char)0x69, (char)0x77, (char)0x6e, (char)0x69, (char)0x77, (char)0x36, (char)0x72, (char)0x69, (char)0x72, (char)0x2e, (char)0x74, (char)0x72, (char)0x6e, (char)0x65, (char)0x6f, (char)0x73, (char)0x2d, (char)0x2e, (char)0x72, (char)0x63, (char)0x76, (char)0x74, (char)0x36, (char)0x65, (char)0x72, (char)0x65, (char)0x6d, (char)0x32, (char)0x72, (char)0x70, (char)0x40, (char)0x65, (char)0x74, (char)0x6e, (char)0x32, (char)0x70, (char)0x2d, (char)0x31, (char)0x40, (char)0x6c, (char)0x65, (char)0x6c, (char)0x76, (char)0x69, (char)0x69, (char)0x76, (char)0x76, (char)0x73, (char)0x31, (char)0x6e, (char)0x65, (char)0x74, (char)0x65, (char)0x6d, (char)0x69, (char)0x2d, (char)0x72, (char)0x74, (char)0x74, (char)0x6c, (char)0x31, (char)0x74, (char)0x6e, (char)0x6e, (char)0x65, (char)0x77, (char)0x36, (char)0x69, (char)0x69, (char)0x72, (char)0x6e, (char)0x2d, (char)0x2d, (char)0x2d, (char)0x72, (char)0x73, (char)0x76, (char)0x72, (char)0x72, (char)0x65, (char)0x72, (char)0x65, (char)0x72, (char)0x2d, (char)0x6c, (char)0x76, (char)0x77, (char)0x63, (char)0x77, (char)0x72, (char)0x6d, (char)0x72, (char)0x2e, (char)0x65, (char)0x73, (char)0x32, (char)0x72, (char)0x36, (char)0x77, (char)0x72, (char)0x72, (char)0x6d, (char)0x74, (char)0x2d, (char)0x72, (char)0x2e, (char)0x73, (char)0x73, (char)0x65, (char)0x77, (char)0x6e, (char)0x65, (char)0x69, (char)0x65, (char)0x2d, (char)0x65, (char)0x77, (char)0x6f, (char)0x74, (char)0x72, (char)0x32, (char)0x40, (char)0x6e, (char)0x72, (char)0x69, (char)0x6e, (char)0x32, (char)0x70, (char)0x73, (char)0x72, (char)0x40, (char)0x2d, (char)0x65, (char)0x69, (char)0x65, (char)0x77, (char)0x65, (char)0x70, (char)0x40, (char)0x36, (char)0x72, (char)0x6c, (char)0x6d, (char)0x73, (char)0x69, (char)0x72, (char)0x72, (char)0x74, (char)0x36, (char)0x6c, (char)0x76, (char)0x65, (char)0x76, (char)0x2d, (char)0x74, (char)0x6c, (char)0x72, (char)0x72, (char)0x74, (char)0x6e, (char)0x73, (char)0x74, (char)0x69, (char)0x72, (char)0x6d, (char)0x40, (char)0x2d, (char)0x6e, (char)0x70, (char)0x73, (char)0x2d, (char)0x6d, (char)0x72, (char)0x72, (char)0x70, (char)0x65, (char)0x65, (char)0x36, (char)0x6e, (char)0x77, (char)0x2d, (char)0x69, (char)0x2d, (char)0x32, (char)0x72, (char)0x6d, (char)0x72, (char)0x6c, (char)0x32, (char)0x6c, (char)0x73, (char)0x6d, (char)0x65, (char)0x36, (char)0x69, (char)0x69, (char)0x72, (char)0x77, (char)0x74, (char)0x6f, (char)0x72, (char)0x6d, (char)0x6d, (char)0x69, (char)0x65, (char)0x73, (char)0x63, (char)0x65, (char)0x74, (char)0x74, (char)0x72, (char)0x65, (char)0x72, (char)0x2e, (char)0x6e, (char)0x73, (char)0x65, (char)0x76, (char)0x6c, (char)0x76, (char)0x77, (char)0x72, (char)0x6e, (char)0x6c, (char)0x32, (char)0x2d, (char)0x73, (char)0x65, (char)0x73, (char)0x2e, (char)0x76, (char)0x72, (char)0x65, (char)0x2d, (char)0x72, (char)0x77, (char)0x2d, (char)0x77, (char)0x70, (char)0x65, (char)0x6c, (char)0x72, (char)0x6e, (char)0x2e, (char)0x31, (char)0x73, (char)0x2e, (char)0x72, (char)0x6d, (char)0x6d, (char)0x69, (char)0x74, (char)0x74, (char)0x6d, (char)0x32, (char)0x70, (char)0x76, (char)0x76, (char)0x31, (char)0x76, (char)0x77, (char)0x65, (char)0x6e, (char)0x73, (char)0x63, (char)0x2e, (char)0x2d, (char)0x69, (char)0x6e, (char)0x69, (char)0x77, (char)0x6e, (char)0x65, (char)0x6d, (char)0x2d, (char)0x72, (char)0x6e, (char)0x74, (char)0x6e, (char)0x40, (char)0x73, (char)0x2d, (char)0x74, (char)0x74, (char)0x65, (char)0x72, (char)0x2d, (char)0x2d, (char)0x69, (char)0x73, (char)0x70,
            (char)0x69, (char)0x6c, (char)0x72, (char)0x76, (char)0x6d, (char)0x74, (char)0x6e, (char)0x73, (char)0x74, (char)0x72, (char)0x65, (char)0x63, (char)0x69, (char)0x65, (char)0x65, (char)0x72, (char)0x6f, (char)0x6e, (char)0x72, (char)0x72, (char)0x6c, (char)0x6e, (char)0x6e, (char)0x65, (char)0x6d, (char)0x74, (char)0x6c, (char)0x74, (char)0x65, (char)0x69, (char)0x2d, (char)0x6f, (char)0x69, (char)0x2e, (char)0x6e, (char)0x63, (char)0x65, (char)0x6c, (char)0x40, (char)0x70, (char)0x2d, (char)0x2d, (char)0x74, (char)0x73, (char)0x74, (char)0x40, (char)0x72, (char)0x74, (char)0x6c, (char)0x72, (char)0x6e, (char)0x6f, (char)0x73, (char)0x65, (char)0x74, (char)0x6d, (char)0x69, (char)0x32, (char)0x72, (char)0x65, (char)0x77, (char)0x6e, (char)0x76, (char)0x74, (char)0x73, (char)0x2d, (char)0x72, (char)0x6e, (char)0x69, (char)0x73, (char)0x40, (char)0x36, (char)0x2d, (char)0x6d, (char)0x2e, (char)0x65, (char)0x6d, (char)0x40, (char)0x69, (char)0x72, (char)0x72, (char)0x70, (char)0x65, (char)0x72, (char)0x76, (char)0x6c, (char)0x65, (char)0x76, (char)0x72, (char)0x65, (char)0x69, (char)0x65, (char)0x69, (char)0x6e, (char)0x72, (char)0x2d, (char)0x63, (char)0x72, (char)0x69, (char)0x6e, (char)0x72, (char)0x69, (char)0x6e, (char)0x69, (char)0x70, (char)0x6e, (char)0x2d, (char)0x69, (char)0x6c, (char)0x72, (char)0x2d, (char)0x65, (char)0x2d, (char)0x72, (char)0x6f, (char)0x65, (char)0x6e, (char)0x76, (char)0x6e, (char)0x40, (char)0x2d, (char)0x65, (char)0x72, (char)0x72, (char)0x6f, (char)0x6f, (char)0x72, (char)0x6c, (char)0x65, (char)0x74, (char)0x73, (char)0x72, (char)0x70, (char)0x77, (char)0x69, (char)0x69, (char)0x6d, (char)0x6c, (char)0x6d, (char)0x6e, (char)0x2d, (char)0x65, (char)0x65, (char)0x65, (char)0x74, (char)0x6c, (char)0x2d, (char)0x74, (char)0x6f, (char)0x2d, (char)0x74, (char)0x70, (char)0x72, (char)0x6e, (char)0x73, (char)0x72, (char)0x69, (char)0x72, (char)0x2e, (char)0x6d, (char)0x69, (char)0x65, (char)0x65, (char)0x32, (char)0x70, (char)0x6c, (char)0x6c, (char)0x65, (char)0x77, (char)0x2d, (char)0x72, (char)0x6f, (char)0x70, (char)0x76, (char)0x65, (char)0x2d, (char)0x72, (char)0x69, (char)0x6d, (char)0x72, (char)0x36, (char)0x40, (char)0x6d, (char)0x72, (char)0x6c, (char)0x6d, (char)0x77, (char)0x6c, (char)0x6e, (char)0x69, (char)0x72, (char)0x6d, (char)0x76, (char)0x73, (char)0x2e, (char)0x73, (char)0x72, (char)0x77, (char)0x73, (char)0x76, (char)0x2d, (char)0x73, (char)0x76, (char)0x6d, (char)0x76, (char)0x65, (char)0x69, (char)0x76, (char)0x63, (char)0x65, (char)0x72, (char)0x31, (char)0x72, (char)0x69, (char)0x76, (char)0x72, (char)0x65, (char)0x65, (char)0x2d, (char)0x73, (char)0x6d, (char)0x31, (char)0x72, (char)0x6e, (char)0x72, (char)0x2d, (char)0x2d, (char)0x36, (char)0x72, (char)0x73, (char)0x77, (char)0x2d, (char)0x77, (char)0x36, (char)0x76, (char)0x72, (char)0x6d, (char)0x65, (char)0x2d, (char)0x72, (char)0x70, (char)0x2d, (char)0x74, (char)0x32, (char)0x6c, (char)0x63, (char)0x6d, (char)0x6f, (char)0x6e, (char)0x2e, (char)0x2d, (char)0x69, (char)0x65, (char)0x73, (char)0x6d, (char)0x65, (char)0x73, (char)0x6e, (char)0x6d, (char)0x6c, (char)0x65, (char)0x6e, (char)0x72, (char)0x72, (char)0x72, (char)0x32, (char)0x70, (char)0x65, (char)0x73, (char)0x6c, (char)0x6d, (char)0x70, (char)0x6d, (char)0x72, (char)0x6f, (char)0x65, (char)0x6c, (char)0x76, (char)0x73, (char)0x63, (char)0x73, (char)0x65, (char)0x6c, (char)0x2d, (char)0x6e, (char)0x72, (char)0x65, (char)0x65, (char)0x72, (char)0x2d, (char)0x70, (char)0x6d, (char)0x69, (char)0x69, (char)0x65, (char)0x2d, (char)0x6c, (char)0x72, (char)0x69, (char)0x6c, (char)0x2d, (char)0x74, (char)0x65, (char)0x65, (char)0x69, (char)0x31, (char)0x72, (char)0x69, (char)0x6d, (char)0x69, (char)0x74, (char)0x74, (char)0x73, (char)0x65, (char)0x32, (char)0x2d, (char)0x6f, (char)0x2d, (char)0x70, (char)0x72, (char)0x6f, (char)0x65, (char)0x69, (char)0x73, (char)0x32, (char)0x6d, (char)0x65, (char)0x2d, (char)0x65, (char)0x74, (char)0x6d, (char)0x6d, (char)0x73, (char)0x76, (char)0x6c, (char)0x69, (char)0x65, (char)0x2d, (char)0x73, (char)0x74, (char)0x65, (char)0x65, (char)0x72, (char)0x72, (char)0x74, (char)0x31, (char)0x2d, (char)0x76, (char)0x73, (char)0x2e, (char)0x2d, (char)0x2d, (char)0x72, (char)0x76, (char)0x77, (char)0x65, (char)0x72, (char)0x72, (char)0x40, (char)0x6e, (char)0x6c, (char)0x6d, (char)0x72, (char)0x74, (char)0x73, (char)0x72, (char)0x72, (char)0x65, (char)0x65, (char)0x2d, (char)0x6f, (char)0x74, (char)0x70, (char)0x63, (char)0xb8, (char)0xa1, (char)0x11, (char)0x6e, (char)0xd7, (char)0x74, (char)0x16, (char)0x7f, (char)0xb4, (char)0xba, (char)0x40, (char)0x93, (char)0x98, (char)0x00, (char)0x71, (char)0xcc, (char)0x42, (char)0xa7, (char)0x2f, (char)0x28, (char)0x69, (char)0xe7, (char)0x31, (char)0x48, (char)0x22, (char)0xa0, (char)0xe1, (char)0x45, (char)0xe3, (char)0xf7, (char)0x7f, (char)0x3a
        };
        char c2[] = {
            (char)0x5b, (char)0x52, (char)0xf1, (char)0x2d, (char)0x94, (char)0xcb, (char)0xb0, (char)0x86, (char)0xd8, (char)0xd3, (char)0xe3, (char)0x20, (char)0x88, (char)0x47, (char)0xcf, (char)0x5a, (char)0x49, (char)0xd2, (char)0x11, (char)0x30, (char)0x92, (char)0x17, (char)0x8d, (char)0xf4, (char)0x99, (char)0xf7, (char)0x6c, (char)0x8a, (char)0xbc, (char)0xe7, (char)0x5c, (char)0x58, (char)0x6a, (char)0x65, (char)0xed, (char)0x81, (char)0xdc, (char)0xdd, (char)0xcf, (char)0x83, (char)0xcd, (char)0xa4, (char)0xed, (char)0xa2, (char)0x5e, (char)0x63, (char)0xd9, (char)0x98, (char)0xf6, (char)0x2e, (char)0x15, (char)0x76, (char)0x9a, (char)0xc8, (char)0x8c, (char)0x42, (char)0x54, (char)0x44, (char)0xf4, (char)0x47, (char)0xf5, (char)0x96, (char)0xc9, (char)0x6e, (char)0x23, (char)0x09, (char)0x1a, (char)0x0d, (char)0xe3, (char)0x04, (char)0xe6, (char)0xed, (char)0x48, (char)0x49, (char)0x62, (char)0x31, (char)0xe8, (char)0x36, (char)0x04, (char)0xed, (char)0xb9, (char)0xe7, (char)0xa6, (char)0x35, (char)0x4d, (char)0xcd, (char)0xe3, (char)0xfa, (char)0xa0, (char)0xc8, (char)0x34, (char)0xbd, (char)0x62, (char)0x7b, (char)0xbc, (char)0xbe, (char)0x1c, (char)0x5b, (char)0x69, (char)0x1f, (char)0x9c, (char)0x30, (char)0x20, (char)0x48, (char)0x52, (char)0xd1, (char)0xb6, (char)0x5e, (char)0xa2, (char)0x6e, (char)0x06, (char)0x94, (char)0x72, (char)0x10, (char)0x56, (char)0x7c, (char)0x94, (char)0xa5, (char)0xc0, (char)0xaa, (char)0xea, (char)0x48, (char)0x61, (char)0x03, (char)0x14, (char)0x94, (char)0x09, (char)0x77, (char)0xd9, (char)0xa7, (char)0xfe, (char)0x78, (char)0x17, (char)0x95, (char)0x4f, (char)0x7e, (char)0xb0, (char)0x32, (char)0x63, (char)0x02, (char)0x17, (char)0x47, (char)0x1e, (char)0x7d, (char)0xb2, (char)0x7d, (char)0xb5, (char)0xcb, (char)0x9f, (char)0x61, (char)0x65, (char)0xed, (char)0x03, (char)0xd2, (char)0xdb, (char)0xd1, (char)0xb3, (char)0xd6, (char)0x1a, (char)0xf5, (char)0x67, (char)0x0b, (char)0x8b, (char)0x6b, (char)0x44, (char)0xf2, (char)0x62, (char)0x42, (char)0xc2, (char)0x4d, (char)0xe1, (char)0x5c, (char)0xfe, (char)0xc6, (char)0x19, (char)0x2b, (char)0xfb, (char)0x03, (char)0x0f, (char)0x1b, (char)0x89, (char)0x08, (char)0x86, (char)0x40, (char)0xca, (char)0x45, (char)0x15, (char)0xda, (char)0x65, (char)0xcc, (char)0x73, (char)0x00, (char)0x49, (char)0x4e, (char)0x48, (char)0x21, (char)0x25, (char)0xc6, (char)0xde, (char)0x26, (char)0x21, (char)0x1d, (char)0xea, (char)0x3c, (char)0x11, (char)0xac, (char)0xef, (char)0x34, (char)0x4c, (char)0x96, (char)0xcc, (char)0x5e, (char)0x26, (char)0xf3, (char)0xcd, (char)0x70, (char)0x0d, (char)0x62, (char)0xea, (char)0x09, (char)0x35, (char)0x2b, (char)0x1e, (char)0x60, (char)0xe4, (char)0x76, (char)0xd3, (char)0x65, (char)0x01, (char)0x8c, (char)0xab, (char)0xd4, (char)0x89, (char)0xad, (char)0x81, (char)0x9d, (char)0x04, (char)0x01, (char)0xd5, (char)0x55, (char)0x3c, (char)0xcb, (char)0x32, (char)0xe1, (char)0xb5, (char)0xd4, (char)0xda, (char)0xb4, (char)0xa9, (char)0x01, (char)0xb2, (char)0x10, (char)0xc7, (char)0xb1, (char)0xa9, (char)0x54, (char)0x66, (char)0x1d, (char)0xcc, (char)0xff, (char)0x54, (char)0x0b, (char)0x84, (char)0x37, (char)0xe0, (char)0x3a, (char)0xa5, (char)0x68, (char)0x80, (char)0x87, (char)0xbc, (char)0x3c, (char)0x0f, (char)0xda, (char)0x7e, (char)0x3c, (char)0x23, (char)0xfc, (char)0xd8, (char)0xc5, (char)0x52, (char)0xf7, (char)0x22, (char)0x12, (char)0x05, (char)0x9c, (char)0x68, (char)0x39, (char)0xb1, (char)0xed, (char)0x26, (char)0x24, (char)0x2b, (char)0x7e, (char)0x0b, (char)0xaf, (char)0x9e, (char)0x97, (char)0x45, (char)0x7b, (char)0xa9, (char)0xbc, (char)0x48, (char)0x0e, (char)0x66, (char)0x93, (char)0x32, (char)0x0d, (char)0x6b, (char)0xd6, (char)0xf0, (char)0x4f, (char)0x54, (char)0x18, (char)0xcd, (char)0xc9, (char)0x8c, (char)0xce, (char)0xc4, (char)0xa2, (char)0xff, (char)0x1e, (char)0x69, (char)0x17, (char)0x7e, (char)0xf4, (char)0x99, (char)0x09, (char)0x68, (char)0xa1, (char)0x9e, (char)0x1f, (char)0xbf, (char)0x90, (char)0xdc, (char)0x77, (char)0x5d, (char)0x50, (char)0x2b, (char)0x0e, (char)0xff, (char)0x96, (char)0xdc, (char)0x21, (char)0x2e, (char)0x74, (char)0x22, (char)0x28, (char)0x88, (char)0xa0, (char)0x00, (char)0x32, (char)0x15, (char)0xb0, (char)0xfd, (char)0xb1, (char)0xc9, (char)0x75, (char)0xb3, (char)0x3c, (char)0xbd, (char)0x89, (char)0xc5, (char)0xa4, (char)0x48, (char)0x17, (char)0xa9, (char)0xc9, (char)0x50, (char)0x61, (char)0x0c, (char)0x35, (char)0x31, (char)0x55, (char)0x11, (char)0xe3, (char)0x23, (char)0xe9, (char)0x3e, (char)0x78, (char)0x25, (char)0xdc, (char)0x50, (char)0xe8, (char)0x23, (char)0x5f, (char)0xb7, (char)0x3f, (char)0xc7, (char)0xae, (char)0xf0, (char)0x82, (char)0x35, (char)0x46, (char)0x34, (char)0x63, (char)0xcc, (char)0x5d, (char)0x96, (char)0xb8, (char)0x6a, (char)0x7a, (char)0x7f, (char)0x54, (char)0x27, (char)0x1a, (char)0xa4, (char)0x63, (char)0xdd, (char)0xb0, (char)0xb6, (char)0x17, (char)0x08, (char)0xa1, (char)0x2e, (char)0x95, (char)0x9e, (char)0xd4, (char)0x9b, (char)0x71, (char)0x83, (char)0x81, (char)0x6c, (char)0xea, (char)0xab, (char)0x00, (char)0x2e, (char)0xca, (char)0x60, (char)0xc1, (char)0x4b, (char)0x83, (char)0xa7, (char)0xab, (char)0x47, (char)0xe8, (char)0x1b, (char)0x5a, (char)0x78, (char)0x4f, (char)0xec, (char)0xbd, (char)0x62, (char)0x94, (char)0x25, (char)0x75, (char)0x2e, (char)0x64, (char)0xe7, (char)0x70, (char)0x13, (char)0xac, (char)0xe9, (char)0x89, (char)0x4f, (char)0x1e, (char)0x79, (char)0xbc, (char)0x15, (char)0x0c, (char)0x8d, (char)0x40, (char)0xe8, (char)0x16, (char)0x31, (char)0x7c, (char)0xb8, (char)0xa5, (char)0xd7, (char)0x21, (char)0x39, (char)0x93, (char)0x9b, (char)0xe6, (char)0x05, (char)0x81, (char)0xb6, (char)0x20, (char)0xa8, (char)0x5d, (char)0x73, (char)0x58, (char)0x8b, (char)0x66, (char)0x92, (char)0xac, (char)0x23, (char)0xa0, (char)0xf4, (char)0x8c, (char)0xab, (char)0x58, (char)0xae, (char)0xb6, (char)0x9c, (char)0x3c, (char)0x4d, (char)0x77, (char)0x5f, (char)0xae, (char)0xe2, (char)0x57, (char)0x89, (char)0x8f, (char)0xe4, (char)0x68, (char)0x81, (char)0x24, (char)0x7d, (char)0x3b, (char)0x99, (char)0x46, (char)0x9f, (char)0x7b, (char)0x9d, (char)0xa6, (char)0xdd, (char)0x99, (char)0xcf, (char)0xc1, (char)0x79, (char)0x04, (char)0x95, (char)0xce, (char)0x96, (char)0x7a, (char)0xd9, (char)0xb5, (char)0x6e, (char)0xcf, (char)0xd1, (char)0x72, (char)0x18, (char)0x97, (char)0x76, (char)0xe2, (char)0xb7, (char)0x38, (char)0x1e, (char)0x24, (char)0x0b, (char)0x09, (char)0x00, (char)0x8b, (char)0x28, (char)0x5d, (char)0xf8, (char)0xd0, (char)0x50, (char)0x7f, (char)0xeb, (char)0x3b, (char)0x37, (char)0x61, (char)0x0b, (char)0xd3, (char)0xff, (char)0x65, (char)0x7d, (char)0x88, (char)0x1e, (char)0x1d, (char)0xbb, (char)0x6c, (char)0xf5, (char)0xf8, (char)0xf3, (char)0x2b, (char)0x51, (char)0xd9, (char)0x6d, (char)0xc9, (char)0xbe, (char)0xbe, (char)0xd1, (char)0x94, (char)0x0e, (char)0x58, (char)0x2a, (char)0x0a, (char)0xe4, (char)0xf8, (char)0x28, (char)0x26, (char)0xc3, (char)0x74, (char)0x87, (char)0xd3, (char)0x81, (char)0x48, (char)0x6e, (char)0x9b, (char)0xd5, (char)0xa1, (char)0x60, (char)0x87, (char)0xfc, (char)0x1b, (char)0x06, (char)0x33, (char)0x0d, (char)0x87, (char)0xfa, (char)0x9b, (char)0xf9, (char)0x73, (char)0x6b, (char)0x0c, (char)0xdf, (char)0xea, (char)0xee, (char)0x32, (char)0x78, (char)0xe0, (char)0xf8, (char)0x18, (char)0x3f, (char)0xc3, (char)0x3b, (char)0x12, (char)0x88, (char)0x0b, (char)0xb2, (char)0x4a, (char)0x52, (char)0x64, (char)0x4e, (char)0x58, (char)0x54, (char)0x82, (char)0x52, (char)0x61, (char)0x54, (char)0x28, (char)0x1b, (char)0xf7, (char)0x99, (char)0x06, (char)0xa2, (char)0xad, (char)0x04, (char)0x19, (char)0x9f, (char)0x2e, (char)0x34, (char)0xe6, (char)0xf0, (char)0xee, (char)0xeb, (char)0x93, (char)0x9a, (char)0x9c, (char)0x73, (char)0x86, (char)0x23, (char)0x6d, (char)0x5d, (char)0xae, (char)0x64, (char)0xec, (char)0x6f, (char)0xf9, (char)0x7c, (char)0xc7, (char)0x46, (char)0x96, (char)0xdb, (char)0x44, (char)0xf4, (char)0xab, (char)0xc9, (char)0x67, (char)0x61, (char)0xb8, (char)0xec, (char)0xf0, (char)0x99, (char)0xe0, (char)0x4d, (char)0x45, (char)0xed, (char)0xa3, (char)0x1c, (char)0xe9, (char)0x68, (char)0x31, (char)0x85, (char)0xa5, (char)0xa1, (char)0xba, (char)0x08, (char)0xdb, (char)0x3f, (char)0x84, (char)0x75, (char)0x70, (char)0x24, (char)0xcd, (char)0x49, (char)0xd4, (char)0x07, (char)0xa8, (char)0xaa, (char)0x52, (char)0xd9, (char)0x55, (char)0x68, (char)0x8f, (char)0x78, (char)0xd2, (char)0x5d, (char)0x46, (char)0x23, (char)0x60, (char)0x76, (char)0xe1, (char)0x22, (char)0xdc, (char)0x2a, (char)0xeb, (char)0xac, (char)0xbc, (char)0xeb, (char)0xd6, (char)0x4c, (char)0x0f, (char)0xb5, (char)0xcb, (char)0x47, (char)0xce, (char)0x43, (char)0x59, (char)0x1d, (char)0x3e, (char)0xfc, (char)0x7f, (char)0x7c, (char)0x93, (char)0x9e, (char)0xef, (char)0xcd, (char)0x79, (char)0x5c, (char)0x08, (char)0x8e, (char)0xeb, (char)0xa8, (char)0x98, (char)0x3e, (char)0x95, (char)0xd1, (char)0x36, (char)0x42, (char)0x57, (char)0xfd, (char)0x6d, (char)0xdc, (char)0xe0, (char)0xa3, (char)0x3f, (char)0x46, (char)0x32, (char)0xb7, (char)0xff, (char)0x00, (char)0x4f, (char)0x7b, (char)0x23, (char)0x4d, (char)0xd0, (char)0xe5, (char)0xdd, (char)0x40, (char)0xab, (char)0xb2, (char)0xcb, (char)0x45, (char)0x92, (char)0x76, (char)0x7c, (char)0x5b, (char)0x98, (char)0xc7, (char)0xc0, (char)0x54, (char)0x34, (char)0x94, (char)0x8e, (char)0xbb, (char)0x28, (char)0xcf, (char)0xba, (char)0xd9, (char)0xa0, (char)0xe6, (char)0xf3, (char)0x65, (char)0x61, (char)0xd7, (char)0x10, (char)0xd3, (char)0xeb, (char)0xce, (char)0x21, (char)0x6a, (char)0xca, (char)0x61, (char)0xe7, (char)0x81, (char)0x15, (char)0x18, (char)0x4e, (char)0x71, (char)0xb0, (char)0x99, (char)0x62, (char)0xd9, (char)0xeb, (char)0xd0, (char)0x8b, (char)0xe9, (char)0xdf, (char)0x6a, (char)0x6d, (char)0x59, (char)0x0b, (char)0x45, (char)0x93, (char)0x38, (char)0xfe, (char)0xe6, (char)0x6a, (char)0xd1, (char)0x5f, (char)0xb6, (char)0xe9, (char)0x86, (char)0x01, (char)0x38, (char)0xab, (char)0x59, (char)0x5c, (char)0xd7, (char)0xb7, (char)0xfa, (char)0x81, (char)0x8a, (char)0xbe, (char)0xdc, (char)0xeb, (char)0x50, (char)0x7d, (char)0x81, (char)0xfa, (char)0x1b, (char)0x8f, (char)0xce, (char)0x53, (char)0x38, (char)0xe4, (char)0x8a, (char)0x82, (char)0xbe, (char)0x7d, (char)0xdc, (char)0xd8, (char)0x57, (char)0x5a, (char)0x48, (char)0xa3, (char)0x38, (char)0x74, (char)0x8a, (char)0xac, (char)0xf2, (char)0xfd, (char)0xbf, (char)0xcc, (char)0xd8, (char)0x08, (char)0x4d, (char)0x3e, (char)0xae, (char)0xa9, (char)0x00, (char)0x66, (char)0x06, (char)0xcb, (char)0xf3,
            (char)0x50, (char)0xcc, (char)0x52, (char)0xc7, (char)0x4b, (char)0x16, (char)0x33, (char)0xa5, (char)0xde, (char)0x20, (char)0xed, (char)0x6a, (char)0xa7, (char)0x58, (char)0x5e, (char)0x4e, (char)0x7e, (char)0x29, (char)0xab, (char)0xb9, (char)0x65, (char)0x9d, (char)0x17, (char)0xe0, (char)0x1e, (char)0x79, (char)0x77, (char)0xf6, (char)0x1e, (char)0xa0, (char)0xcb, (char)0x0c, (char)0xf7, (char)0xc0, (char)0xe4, (char)0xf6, (char)0x3b, (char)0x60, (char)0x81, (char)0xfe, (char)0xed, (char)0xd9, (char)0x42, (char)0xa9, (char)0x61, (char)0x9d, (char)0xa8, (char)0xd7, (char)0xe8, (char)0xaa, (char)0x97, (char)0xad, (char)0xbb, (char)0xba, (char)0x13, (char)0x6e, (char)0x05, (char)0xa5, (char)0xce, (char)0x7a, (char)0x65, (char)0x6f, (char)0x55, (char)0xe3, (char)0xcf, (char)0xbc, (char)0x67, (char)0x14, (char)0x64, (char)0x57, (char)0x9c, (char)0x46, (char)0x14, (char)0xd6, (char)0x1d, (char)0x39, (char)0x1c, (char)0xd3, (char)0xe8, (char)0x98, (char)0x20, (char)0x5a, (char)0x1a, (char)0x05, (char)0x3b, (char)0x27, (char)0xd5, (char)0x84, (char)0xca, (char)0xd4, (char)0x0b, (char)0xc4, (char)0x1e, (char)0xd8, (char)0x46, (char)0x29, (char)0x48, (char)0x95, (char)0xdb, (char)0xe5, (char)0x58, (char)0x8a, (char)0x51, (char)0xc7, (char)0x74, (char)0x7f, (char)0x53, (char)0xa8, (char)0xbb, (char)0x58, (char)0xc0, (char)0x5b, (char)0xe1, (char)0xa7, (char)0x27, (char)0x36, (char)0x6c, (char)0xa6, (char)0x70, (char)0xec, (char)0x88, (char)0xcd, (char)0x9a, (char)0x70, (char)0xe1, (char)0xa0, (char)0xc7, (char)0xdd, (char)0x60, (char)0x71, (char)0xf4, (char)0x2a, (char)0x51, (char)0x98, (char)0x8e, (char)0xab, (char)0xb8, (char)0x13, (char)0x03, (char)0x48, (char)0x5f, (char)0x44, (char)0xf8, (char)0x88, (char)0xd9, (char)0x7d, (char)0xd3, (char)0xf1, (char)0x5f, (char)0xc4, (char)0x2b, (char)0x44, (char)0x15, (char)0x57, (char)0x31, (char)0xa4, (char)0xa1, (char)0xdb, (char)0x6d, (char)0x2a, (char)0x5a, (char)0x5a, (char)0xf7, (char)0xde, (char)0xd5, (char)0x23, (char)0x38, (char)0x00, (char)0xe5, (char)0x5c, (char)0x55, (char)0xe7, (char)0x37, (char)0x9c, (char)0xcb, (char)0x8b, (char)0xc0, (char)0x33, (char)0x42, (char)0x68, (char)0x23, (char)0x84, (char)0x7d, (char)0x89, (char)0x9d, (char)0xae, (char)0x59, (char)0x18, (char)0xae, (char)0xea, (char)0x46, (char)0x3f, (char)0xac, (char)0x57, (char)0x0d, (char)0x5d, (char)0x49, (char)0x14, (char)0x50, (char)0xe5, (char)0x70, (char)0x17, (char)0x73, (char)0x09, (char)0x11, (char)0x93, (char)0x6b, (char)0x02, (char)0x22, (char)0xb7, (char)0x63, (char)0xc9, (char)0xe6, (char)0xa4, (char)0xe3, (char)0xb1, (char)0xf7, (char)0xa6, (char)0x58, (char)0x8d, (char)0x14, (char)0xa1, (char)0xda, (char)0x6a, (char)0xb9, (char)0x38, (char)0xf9, (char)0x20, (char)0x45, (char)0x8c, (char)0xe6, (char)0x32, (char)0x23, (char)0x9d, (char)0x5f, (char)0xba, (char)0xcb, (char)0xb4, (char)0x95, (char)0xf9, (char)0xa9, (char)0x5c, (char)0x60, (char)0x03, (char)0x5a, (char)0x8c, (char)0xa7, (char)0xb9, (char)0x65, (char)0xa8, (char)0x84, (char)0x38, (char)0xc0, (char)0x25, (char)0xe6, (char)0xa7, (char)0xc0, (char)0x3b, (char)0xbc, (char)0x11, (char)0xed, (char)0x0e, (char)0x9a, (char)0x6f, (char)0xfe, (char)0x61, (char)0x79, (char)0x86, (char)0x92, (char)0x3a, (char)0xce, (char)0xe0, (char)0xb7, (char)0x70, (char)0xad, (char)0xe0, (char)0xcc, (char)0x88, (char)0x47, (char)0xd9, (char)0x2a, (char)0x3d, (char)0x41, (char)0x06, (char)0x77, (char)0x41, (char)0xbe, (char)0x3f, (char)0x55, (char)0x31, (char)0x54, (char)0x10, (char)0x14, (char)0x5b, (char)0xdf, (char)0x88, (char)0xb2, (char)0x9f, (char)0xff, (char)0x11, (char)0xb8, (char)0x11, (char)0xdc, (char)0x5e, (char)0x64, (char)0xf9, (char)0x97, (char)0x8a, (char)0x26, (char)0x6a, (char)0x44, (char)0xb4, (char)0x83, (char)0x83, (char)0x9b, (char)0x81, (char)0xaa, (char)0xfd, (char)0xb5, (char)0x8b, (char)0x16, (char)0x18, (char)0x2e, (char)0x5c, (char)0xe4, (char)0x5b, (char)0x8f, (char)0xdd, (char)0x7c, (char)0x1f, (char)0x33, (char)0x2f, (char)0xef, (char)0x57, (char)0x8c, (char)0x6a, (char)0x3f, (char)0x3c, (char)0x19, (char)0x5e, (char)0x73, (char)0x64, (char)0xc5, (char)0xaf, (char)0x1d, (char)0xa1, (char)0xb4, (char)0x11, (char)0xee, (char)0x6b, (char)0x7e, (char)0x66, (char)0xfb, (char)0xaa, (char)0x03, (char)0x17, (char)0xe4, (char)0xc9, (char)0x90, (char)0x4b, (char)0xf2, (char)0x50, (char)0x55, (char)0x71, (char)0xad, (char)0x31, (char)0x71, (char)0x49, (char)0xd7, (char)0x80, (char)0xd1, (char)0xa5, (char)0x9f, (char)0x6d, (char)0x71, (char)0x28, (char)0x2b, (char)0x65, (char)0xcf, (char)0x8d, (char)0xb1, (char)0x2a, (char)0x33, (char)0xdc, (char)0x93, (char)0xff, (char)0x86, (char)0xd7, (char)0xa6, (char)0xd0, (char)0x46, (char)0x66, (char)0x32, (char)0x3d, (char)0x18, (char)0x8c, (char)0xd3, (char)0xda, (char)0xf6, (char)0x1b, (char)0xa0, (char)0x2d, (char)0x29, (char)0xfd, (char)0x8d, (char)0x57, (char)0x2c, (char)0x82, (char)0xed, (char)0x38, (char)0x4a, (char)0x6f, (char)0xc4, (char)0x3c, (char)0x9a, (char)0x61, (char)0xcb, (char)0xe5, (char)0xcf, (char)0xd3, (char)0x83, (char)0xa1, (char)0x91, (char)0x93, (char)0x0d, (char)0x75, (char)0xfd, (char)0x4e, (char)0x2c, (char)0x83, (char)0xa0, (char)0x85, (char)0x27, (char)0x13, (char)0x5a, (char)0x24, (char)0xbd, (char)0x08, (char)0x1e, (char)0xe9, (char)0xab, (char)0x92, (char)0x41, (char)0xc2, (char)0x3a, (char)0xa0, (char)0xe1, (char)0xfd, (char)0x00, (char)0xb9, (char)0xf8, (char)0xca, (char)0x0b, (char)0x1a, (char)0x8e, (char)0xf6, (char)0x27, (char)0x9f, (char)0x5a, (char)0xf0, (char)0x23, (char)0x07, (char)0xc8, (char)0xbf, (char)0xf6, (char)0x74, (char)0xe7, (char)0xf8, (char)0x67, (char)0xfc, (char)0x28, (char)0x4e, (char)0x6a, (char)0x6c, (char)0xc6, (char)0x83, (char)0xe3, (char)0xf0, (char)0x01, (char)0xe0, (char)0x0f, (char)0x2d, (char)0xdf, (char)0x9e, (char)0x4b, (char)0x8b, (char)0x06, (char)0x15, (char)0x4c, (char)0x9f, (char)0xdf, (char)0x55, (char)0x14, (char)0x44, (char)0xde, (char)0x34, (char)0x35, (char)0x5a, (char)0xcb, (char)0xe5, (char)0xa7, (char)0xb5, (char)0x7e, (char)0x00, (char)0x31, (char)0x98, (char)0x5f, (char)0x51, (char)0x11, (char)0x37, (char)0xe1, (char)0xd2, (char)0x99, (char)0x8f, (char)0x70, (char)0x13, (char)0x40, (char)0xa0, (char)0xbe, (char)0xf8, (char)0xde, (char)0xac, (char)0x37, (char)0x06, (char)0xb6, (char)0x26, (char)0xf3, (char)0xb1, (char)0x97, (char)0x0b, (char)0x85, (char)0x68, (char)0x09, (char)0xa4, (char)0xc8, (char)0x34, (char)0x0a, (char)0x41, (char)0x6e, (char)0xac, (char)0x1a, (char)0x5b, (char)0xe0, (char)0x91, (char)0x6f, (char)0xa3, (char)0x0a, (char)0xf6, (char)0x05, (char)0x37, (char)0x32, (char)0xe1, (char)0x8e, (char)0xd8, (char)0xed, (char)0x55, (char)0xa3, (char)0x54, (char)0x3f, (char)0x62, (char)0x95, (char)0x82, (char)0xcf, (char)0x0a, (char)0x19, (char)0xb4, (char)0x9f, (char)0x04, (char)0xcc, (char)0x86, (char)0x7e, (char)0xf1, (char)0xe5, (char)0x8b, (char)0x67, (char)0x73, (char)0xa2, (char)0x46, (char)0x4e, (char)0xf2, (char)0x98, (char)0x94, (char)0xb5, (char)0xeb, (char)0xa5, (char)0xbd, (char)0xcb, (char)0x66, (char)0x82, (char)0xe9, (char)0x87, (char)0xe9, (char)0xe3, (char)0x50, (char)0x55, (char)0x4b, (char)0xd6, (char)0x67, (char)0x30, (char)0xe1, (char)0x7c, (char)0x15, (char)0x77, (char)0x29, (char)0xfd, (char)0x85, (char)0x67, (char)0x5a, (char)0xc4, (char)0xd5, (char)0x69, (char)0xfa, (char)0xc7, (char)0x66, (char)0x66, (char)0x49, (char)0xf7, (char)0x5a, (char)0xcd, (char)0xd1, (char)0x81, (char)0x5c, (char)0x74, (char)0x8d, (char)0xbf, (char)0xc5, (char)0xc2, (char)0xff, (char)0x4d, (char)0x90, (char)0xe8, (char)0x8e, (char)0x05, (char)0x00, (char)0xff, (char)0x7a, (char)0xd7, (char)0xb2, (char)0x7a, (char)0xad, (char)0x8b, (char)0xd6, (char)0x4b, (char)0x52, (char)0x09, (char)0x50, (char)0x4b
        };

        ASSERT_EQ(ERROR_SUCCESS, bytes.create_c0c1());
        memcpy(bytes.c0c1, c0c1, 1537);
        ASSERT_EQ(ERROR_SUCCESS, bytes.create_s0s1s2());
        memcpy(bytes.s0s1s2, s0s1s2, 3073);
        ASSERT_EQ(ERROR_SUCCESS, bytes.create_c2());
        memcpy(bytes.c2, c2, 1536);
    }

    SrsHandshakeBytes* hs_bytes = &bytes;

    if (true) {
        bool is_valid;

        c1s1 c1;
        ASSERT_EQ(ERROR_SUCCESS, c1.parse(hs_bytes->c0c1 + 1, 1536, srs_schema0));
        ASSERT_EQ(ERROR_SUCCESS, c1.c1_validate_digest(is_valid));
        ASSERT_TRUE(is_valid);

        c1s1 s1;
        ASSERT_EQ(ERROR_SUCCESS, s1.parse(hs_bytes->s0s1s2 + 1, 1536, c1.schema()));
        ASSERT_EQ(ERROR_SUCCESS, s1.s1_validate_digest(is_valid));
        ASSERT_TRUE(is_valid);

        c2s2 c2;
        c2.parse(hs_bytes->c2, 1536);
        ASSERT_EQ(ERROR_SUCCESS, c2.c2_validate(&s1, is_valid));
        ASSERT_TRUE(is_valid);

        c2s2 s2;
        s2.parse(hs_bytes->s0s1s2 + 1 + 1536, 1536);
        ASSERT_EQ(ERROR_SUCCESS, s2.s2_validate(&c1, is_valid));
        ASSERT_TRUE(is_valid);
    }
}

#endif

TEST(ProtocolHandshakeTest, SimpleHandshake) {
    char c0c1[] = {
        (char)0x03, (char)0x01, (char)0x14, (char)0xf7, (char)0x4e, (char)0x80, (char)0x00, (char)0x07, (char)0x02, (char)0xac, (char)0x14, (char)0x98, (char)0x57, (char)0x0a, (char)0x07, (char)0x58, (char)0x44, (char)0x96, (char)0x47, (char)0xb5, (char)0x9a, (char)0x73, (char)0xf6, (char)0x07, (char)0x0f, (char)0x49, (char)0x0d, (char)0x72, (char)0xb8, (char)0x16, (char)0xbb, (char)0xb2, (char)0xb7, (char)0x61, (char)0x17, (char)0x79, (char)0xa0, (char)0xe9, (char)0x98, (char)0xca, (char)0xb2, (char)0x86, (char)0x64, (char)0x5f, (char)0x65, (char)0x3e, (char)0xfc, (char)0x4d, (char)0xc0, (char)0x0e, (char)0x4c, (char)0xfa, (char)0x91, (char)0xc7, (char)0x0f, (char)0x2e, (char)0x57, (char)0x31, (char)0x4b, (char)0x96, (char)0xef, (char)0xc9, (char)0x81, (char)0x02, (char)0x00, (char)0x54, (char)0x25, (char)0x2b, (char)0xb2, (char)0x0d, (char)0x7c, (char)0xee, (char)0xba, (char)0xdb, (char)0xe4, (char)0x06, (char)0x78, (char)0xcd, (char)0x70, (char)0x2c, (char)0x54, (char)0x5a, (char)0x3a, (char)0x03, (char)0x13, (char)0x2e, (char)0xe7, (char)0x4b, (char)0x87, (char)0x40, (char)0x77, (char)0x0b, (char)0x9f, (char)0xd2, (char)0xab, (char)0x32, (char)0x07, (char)0x6f, (char)0x1e, (char)0x75, (char)0x74, (char)0xe9, (char)0xc7, (char)0x44, (char)0xd9, (char)0x76, (char)0x53, (char)0xba, (char)0xe2, (char)0x52, (char)0xfa, (char)0xcc, (char)0xef, (char)0x34, (char)0xd5, (char)0x14, (char)0x61, (char)0xac, (char)0xcc, (char)0x63, (char)0xfd, (char)0x2b, (char)0x2d, (char)0xb3, (char)0xb8, (char)0xdd, (char)0x8a, (char)0x51, (char)0x9a, (char)0x2d, (char)0x0e, (char)0xfa, (char)0x84, (char)0x25, (char)0x55, (char)0xb2, (char)0xb7, (char)0x94, (char)0x54, (char)0x68, (char)0xfb, (char)0x94, (char)0xdf, (char)0xd8, (char)0xeb, (char)0x43, (char)0xd0, (char)0x11, (char)0x70, (char)0x8f, (char)0xf5, (char)0x48, (char)0xfc, (char)0x69, (char)0x4d, (char)0x5b, (char)0xc6, (char)0x53, (char)0x8a, (char)0x22, (char)0xea, (char)0x62, (char)0x84, (char)0x89, (char)0x6b, (char)0xfe, (char)0x4e, (char)0xab, (char)0x51, (char)0x98, (char)0xf4, (char)0x4f, (char)0xae, (char)0xf8, (char)0xdf, (char)0xac, (char)0x43, (char)0xed, (char)0x5a, (char)0x04, (char)0x97, (char)0xc4, (char)0xbe, (char)0x44, (char)0x5b, (char)0x99, (char)0x20, (char)0x68, (char)0x67, (char)0x0f, (char)0xe3, (char)0xfa, (char)0x4c, (char)0x9d, (char)0xe7, (char)0x0b, (char)0x3f, (char)0x80, (char)0x7c, (char)0x4c, (char)0x35, (char)0xf6, (char)0xdd, (char)0x20, (char)0x05, (char)0xfd, (char)0x0f, (char)0x39, (char)0xb7, (char)0x36, (char)0x45, (char)0x4c, (char)0xb7, (char)0x62, (char)0x92, (char)0x35, (char)0x2a, (char)0xcd, (char)0xb9, (char)0x49, (char)0xea, (char)0x12, (char)0x0b, (char)0x5f, (char)0x39, (char)0xae, (char)0x3b, (char)0x49, (char)0x29, (char)0xe6, (char)0x30, (char)0xc7, (char)0x7c, (char)0x77, (char)0xaf, (char)0x00, (char)0x43, (char)0x4d, (char)0x06, (char)0x45, (char)0x72, (char)0x73, (char)0x25, (char)0x71, (char)0x5e, (char)0x35, (char)0x04, (char)0xbd, (char)0xe9, (char)0x48, (char)0x23, (char)0x64, (char)0x4d, (char)0x15, (char)0x0b, (char)0xc5, (char)0x3f, (char)0x6e, (char)0x3a, (char)0xd5, (char)0xd5, (char)0xa6, (char)0xae, (char)0x3b, (char)0x4c, (char)0x66, (char)0x6a, (char)0x70, (char)0x8b, (char)0xf3, (char)0x6a, (char)0x43, (char)0xc4, (char)0xb9, (char)0xbd, (char)0xa0, (char)0x09, (char)0x72, (char)0xbc, (char)0xce, (char)0x7a, (char)0xea, (char)0x49, (char)0xf2, (char)0x86, (char)0xa7, (char)0xd8, (char)0x4a, (char)0x87, (char)0x28, (char)0xca, (char)0x2c, (char)0x53, (char)0xee, (char)0x96, (char)0x0b, (char)0xbe, (char)0x15, (char)0x14, (char)0xa8, (char)0x00, (char)0xca, (char)0x76, (char)0x08, (char)0x4d, (char)0x0f, (char)0xef, (char)0x78, (char)0x4b, (char)0xf6, (char)0x47, (char)0x60, (char)0xfc, (char)0x16, (char)0x00, (char)0x7c, (char)0x6b, (char)0x49, (char)0x39, (char)0x64, (char)0x36, (char)0xee, (char)0x45, (char)0x3a, (char)0x9a, (char)0xa5, (char)0xbf, (char)0xfb, (char)0x7b, (char)0xe7, (char)0xcf, (char)0x42, (char)0x82, (char)0x48, (char)0x1b, (char)0x30, (char)0xfe, (char)0x0d, (char)0xba, (char)0x10, (char)0xb8, (char)0xe1, (char)0x40, (char)0xcc, (char)0x6f, (char)0x36, (char)0x1c, (char)0x94, (char)0x5d, (char)0x50, (char)0x9e, (char)0x21, (char)0x08, (char)0xc9, (char)0xd5, (char)0xb0, (char)0x32, (char)0x51, (char)0x6a, (char)0x8f, (char)0xfa, (char)0x57, (char)0x8d, (char)0x45, (char)0xd7, (char)0xd2, (char)0xd0, (char)0xd6, (char)0x6c, (char)0x78, (char)0x95, (char)0xe9, (char)0xe1, (char)0x20, (char)0x97, (char)0x1a, (char)0x43, (char)0x40, (char)0xa3, (char)0xb5, (char)0xcc, (char)0x4b, (char)0x12, (char)0x84, (char)0x1e, (char)0x0e, (char)0xd3, (char)0x32, (char)0xca, (char)0x99, (char)0xc3, (char)0x2b, (char)0x78, (char)0x17, (char)0x24, (char)0x6b, (char)0xc7, (char)0xbc, (char)0x9d, (char)0x05, (char)0xc6, (char)0xaf, (char)0x8f, (char)0x19, (char)0x75, (char)0x3c, (char)0x08, (char)0xa6, (char)0x08, (char)0x26, (char)0x5b, (char)0xf4, (char)0x10, (char)0x40, (char)0xaa, (char)0x6a, (char)0x7e, (char)0xb9, (char)0xde, (char)0x0b, (char)0x23, (char)0x3f, (char)0x53, (char)0x5a, (char)0x20, (char)0x13, (char)0x62, (char)0xec, (char)0x53, (char)0x86, (char)0x81, (char)0x1f, (char)0xf6, (char)0x8e, (char)0xe3, (char)0xd1, (char)0xaa, (char)0xb5, (char)0x41, (char)0x87, (char)0x62, (char)0xd2, (char)0xb7, (char)0x09, (char)0x12, (char)0x71, (char)0x01, (char)0x2c, (char)0xac, (char)0x6d, (char)0x9d, (char)0x37, (char)0x46, (char)0x5b, (char)0xdc, (char)0x76, (char)0x2c, (char)0x96, (char)0x61, (char)0x88, (char)0x55, (char)0x5a, (char)0x20, (char)0xc2, (char)0x84, (char)0x95, (char)0xbd, (char)0x72, (char)0xc4, (char)0xb7, (char)0x22, (char)0xae, (char)0xeb, (char)0x49, (char)0x0e, (char)0x16, (char)0xf1, (char)0xf1, (char)0xbf, (char)0xc5, (char)0xc7, (char)0xa8, (char)0x8d, (char)0xfb, (char)0xe1, (char)0x08, (char)0x6c, (char)0xc4, (char)0x79, (char)0x81, (char)0x13, (char)0xe8, (char)0x39, (char)0xbf, (char)0x6e, (char)0x5c, (char)0xa1, (char)0x62, (char)0xfb, (char)0x32, (char)0x2a, (char)0x62, (char)0xf0, (char)0x12, (char)0x07, (char)0x31, (char)0x93, (char)0x40, (char)0xf3, (char)0xc0, (char)0xea, (char)0x1d, (char)0xd8, (char)0x65, (char)0xba, (char)0x12, (char)0xb3, (char)0x9b, (char)0xf5, (char)0x59, (char)0x9c, (char)0x4e, (char)0xf6, (char)0xb9, (char)0xf7, (char)0x85, (char)0xa1, (char)0xd9, (char)0x2f, (char)0x7c, (char)0x8b, (char)0xd0, (char)0xfc, (char)0x53, (char)0x3b, (char)0xed, (char)0x85, (char)0xa4, (char)0xd2, (char)0x5e, (char)0x69, (char)0x61, (char)0x02, (char)0x53, (char)0xb6, (char)0x19, (char)0xc7, (char)0x82, (char)0xea, (char)0x8a, (char)0x45, (char)0x01, (char)0x5d, (char)0x4b, (char)0xb3, (char)0x06, (char)0x86, (char)0x7f, (char)0x4b, (char)0x2f, (char)0xe7, (char)0xa8, (char)0xd0, (char)0x28, (char)0x62, (char)0x02, (char)0xe8, (char)0xf3, (char)0x9e, (char)0x1e, (char)0x72, (char)0x82, (char)0x07, (char)0x9f, (char)0xdd, (char)0xd2, (char)0x83, (char)0x7d, (char)0x89, (char)0x73, (char)0x1b, (char)0x6f, (char)0x35, (char)0x20, (char)0xb7, (char)0x88, (char)0x15, (char)0x92, (char)0xa7, (char)0x11, (char)0xfe, (char)0x81, (char)0x68, (char)0xed, (char)0x14, (char)0x07, (char)0xdf, (char)0x4a, (char)0x06, (char)0x9c, (char)0x5e, (char)0x7e, (char)0x34, (char)0x3a, (char)0x2a, (char)0x8a, (char)0xd3, (char)0xe8, (char)0xf8, (char)0xd4, (char)0xdb, (char)0xe3, (char)0xe9, (char)0x73, (char)0xbf, (char)0xa7, (char)0xe9, (char)0x73, (char)0x62, (char)0xf2, (char)0x9d, (char)0xc1, (char)0xf7, (char)0x51, (char)0xeb, (char)0xff, (char)0xb7, (char)0xe6, (char)0xd9, (char)0xac, (char)0x46, (char)0x06, (char)0x74, (char)0xe2, (char)0x25, (char)0x3f, (char)0x46, (char)0x43, (char)0xce, (char)0x49, (char)0x52, (char)0x25, (char)0x1b, (char)0xf9, (char)0x24, (char)0x5c, (char)0xda, (char)0xfd, (char)0x7f, (char)0xf6, (char)0xef, (char)0xb3, (char)0xd5, (char)0xe9, (char)0x6e, (char)0x35, (char)0xb8, (char)0xd1, (char)0x0e, (char)0x2c, (char)0xc1, (char)0x48, (char)0x5a, (char)0x27, (char)0x0a, (char)0x81, (char)0x01, (char)0x0f, (char)0xe4, (char)0x51, (char)0xcf, (char)0x89, (char)0x36, (char)0xd3, (char)0xe8, (char)0x5e, (char)0x05, (char)0xb9, (char)0x83, (char)0x42, (char)0xf3, (char)0xa5, (char)0x94, (char)0x67, (char)0x6d, (char)0x6a, (char)0x6e, (char)0xad, (char)0xf8, (char)0x90, (char)0xb1, (char)0x1d, (char)0x63, (char)0x18, (char)0x52, (char)0xc1, (char)0xbf, (char)0xbc, (char)0xad, (char)0xf4, (char)0xd2, (char)0xc5, (char)0xef, (char)0xca, (char)0x4c, (char)0xfe, (char)0xa1, (char)0xda, (char)0x15, (char)0x92, (char)0x4c, (char)0x42, (char)0x3d, (char)0xfc, (char)0x80, (char)0x7e, (char)0x49, (char)0x13, (char)0x4e, (char)0xf6, (char)0xe1, (char)0xee, (char)0x70, (char)0xca, (char)0xd9, (char)0x0a, (char)0xde, (char)0x9b, (char)0xea, (char)0xcd, (char)0xf9, (char)0x90, (char)0xfd, (char)0xae, (char)0x09, (char)0xce, (char)0xb6, (char)0xa0, (char)0xf7, (char)0xd1, (char)0xe6, (char)0x0c, (char)0x55, (char)0x1e, (char)0x3f, (char)0xbb, (char)0x1e, (char)0xff, (char)0x3d, (char)0xdb, (char)0xdd, (char)0x27, (char)0x80, (char)0x06, (char)0x53, (char)0x7e, (char)0x0b, (char)0x2a, (char)0x80, (char)0x24, (char)0x51, (char)0x5c, (char)0x6a, (char)0xab, (char)0x32, (char)0x5d, (char)0x37, (char)0x8a, (char)0xf4, (char)0xb7, (char)0x11, (char)0xa7, (char)0xc1, (char)0x9e, (char)0x05, (char)0x2c, (char)0x16, (char)0xc2, (char)0x08, (char)0xe2, (char)0xac, (char)0x1a, (char)0xeb, (char)0x60, (char)0xf8, (char)0xd2, (char)0xea, (char)0x39, (char)0x01, (char)0x1c, (char)0x64, (char)0xbd, (char)0x22, (char)0x80, (char)0x19, (char)0x20, (char)0xc9, (char)0x6f, (char)0xdd, (char)0x5c, (char)0x73, (char)0x8c, (char)0xa1, (char)0x53, (char)0x48, (char)0x2e, (char)0x99, (char)0x1d, (char)0xc0, (char)0x8f, (char)0x28, (char)0xf1, (char)0xe3, (char)0xc5, (char)0xc5, (char)0x65, (char)0x53, (char)0xf2, (char)0x44, (char)0x44, (char)0x24, (char)0xb9, (char)0xe2, (char)0x73, (char)0xe4, (char)0x76, (char)0x14, (char)0x56, (char)0xb8, (char)0x82, (char)0xe3, (char)0xb4, (char)0xfd, (char)0x68, (char)0x31, (char)0xed, (char)0x40, (char)0x10, (char)0x99, (char)0xd3, (char)0x3d, (char)0xe5, (char)0x6b, (char)0x14, (char)0x61, (char)0x66, (char)0x9a, (char)0xf6, (char)0x33, (char)0x98, (char)0xc5, (char)0x4d, (char)0x11, (char)0xbb, (char)0xf8, (char)0x56, (char)0xf8, (char)0x8f, (char)0xd7, (char)0xb9, (char)0xda, (char)0xa3, (char)0x56, (char)0x1a, (char)0xe0, (char)0x9e, (char)0xbe, (char)0x5f, (char)0x56, (char)0xe5, (char)0xb9, (char)0xd8, (char)0xf3, (char)0xbc, (char)0x19, (char)0xf5, (char)0xe9, (char)0x1f, (char)0xd2, (char)0xea, (char)0xf4, (char)0x5a, (char)0xde, (char)0xed, (char)0xd4, (char)0x9e, (char)0xc8, (char)0xf5, (char)0x54,
        (char)0x83, (char)0x8b, (char)0x8c, (char)0x2d, (char)0x24, (char)0x0e, (char)0x30, (char)0xb1, (char)0x84, (char)0xa2, (char)0xbe, (char)0x2c, (char)0x86, (char)0xe6, (char)0x42, (char)0x82, (char)0xaa, (char)0x37, (char)0x64, (char)0x55, (char)0x51, (char)0xbc, (char)0xde, (char)0xc0, (char)0x63, (char)0x88, (char)0xf6, (char)0x31, (char)0x71, (char)0x52, (char)0xd5, (char)0x34, (char)0x0f, (char)0x8e, (char)0xcb, (char)0x28, (char)0x65, (char)0x93, (char)0x1a, (char)0x66, (char)0x3b, (char)0x21, (char)0x00, (char)0xaa, (char)0x7a, (char)0xda, (char)0x2d, (char)0xf6, (char)0x7e, (char)0xb5, (char)0x27, (char)0x79, (char)0xf4, (char)0x50, (char)0x3b, (char)0x10, (char)0x6b, (char)0x3c, (char)0xd7, (char)0x99, (char)0x9d, (char)0xf6, (char)0xc5, (char)0x01, (char)0x91, (char)0xa0, (char)0xd5, (char)0x4f, (char)0xd3, (char)0x76, (char)0x54, (char)0xa8, (char)0x5c, (char)0x35, (char)0x1d, (char)0xe2, (char)0x35, (char)0x6a, (char)0x68, (char)0x67, (char)0x03, (char)0xc4, (char)0x1f, (char)0xe9, (char)0x60, (char)0xb8, (char)0x49, (char)0xb1, (char)0x9a, (char)0x40, (char)0xd9, (char)0x3c, (char)0x4c, (char)0x73, (char)0xaa, (char)0x88, (char)0x63, (char)0xaf, (char)0xfe, (char)0xe8, (char)0xa8, (char)0x0c, (char)0x96, (char)0xbe, (char)0xb4, (char)0x65, (char)0x7c, (char)0x27, (char)0xfb, (char)0xc1, (char)0x27, (char)0x24, (char)0x58, (char)0xab, (char)0x4b, (char)0xa0, (char)0x5a, (char)0x7d, (char)0xc7, (char)0xca, (char)0x2d, (char)0xa5, (char)0x22, (char)0xa7, (char)0xed, (char)0x26, (char)0x87, (char)0xd5, (char)0x44, (char)0x1a, (char)0xc7, (char)0xdd, (char)0xfb, (char)0x60, (char)0xfc, (char)0xe5, (char)0x50, (char)0xd9, (char)0x8d, (char)0xa7, (char)0xdb, (char)0x78, (char)0xb6, (char)0x9d, (char)0x80, (char)0x0f, (char)0xb9, (char)0x5f, (char)0xa7, (char)0x53, (char)0x92, (char)0x5d, (char)0x18, (char)0xce, (char)0x89, (char)0xc2, (char)0x69, (char)0xee, (char)0xcf, (char)0xb6, (char)0x66, (char)0xe5, (char)0x66, (char)0xd2, (char)0xe3, (char)0x35, (char)0x74, (char)0x0b, (char)0x83, (char)0xb6, (char)0xde, (char)0xf1, (char)0xfb, (char)0xb4, (char)0x1d, (char)0x4b, (char)0x94, (char)0x95, (char)0x06, (char)0x82, (char)0xe7, (char)0x1c, (char)0xf8, (char)0xc5, (char)0xe6, (char)0xd0, (char)0xf2, (char)0x17, (char)0x37, (char)0x44, (char)0xfe, (char)0x99, (char)0x43, (char)0x82, (char)0xbb, (char)0x88, (char)0xe4, (char)0x43, (char)0x67, (char)0xcc, (char)0x4d, (char)0x5f, (char)0xa6, (char)0x26, (char)0xd7, (char)0x53, (char)0xd6, (char)0x45, (char)0x96, (char)0x2b, (char)0x63, (char)0xd1, (char)0x2a, (char)0xa1, (char)0x2c, (char)0x41, (char)0x59, (char)0x8b, (char)0xb8, (char)0xc1, (char)0x89, (char)0x03, (char)0x3a, (char)0x61, (char)0x13, (char)0xc4, (char)0x2c, (char)0x37, (char)0xa5, (char)0xbf, (char)0xd7, (char)0xdb, (char)0xd8, (char)0x53, (char)0x5f, (char)0xa1, (char)0xdb, (char)0xdb, (char)0xa5, (char)0x73, (char)0xb6, (char)0xf7, (char)0x74, (char)0xa0, (char)0xf8, (char)0x93, (char)0xf5, (char)0x61, (char)0xee, (char)0x3c, (char)0xe7, (char)0x00, (char)0x01, (char)0x98, (char)0xe0, (char)0xa1, (char)0x22, (char)0xb6, (char)0x9a, (char)0x83, (char)0x44, (char)0xa1, (char)0xe6, (char)0x70, (char)0x56, (char)0x65, (char)0x92, (char)0x1e, (char)0xf0, (char)0xbc, (char)0x73, (char)0xa5, (char)0x7a, (char)0xc1, (char)0x1a, (char)0x02, (char)0xf9, (char)0xd4, (char)0xc4, (char)0x7c, (char)0x81, (char)0xda, (char)0x15, (char)0xc0, (char)0xd4, (char)0x25, (char)0xdc, (char)0x17, (char)0xa6, (char)0x0d, (char)0x90, (char)0x55, (char)0xf2, (char)0x10, (char)0xf8, (char)0xa7, (char)0x71, (char)0x9b, (char)0xed, (char)0xdf, (char)0xdf, (char)0xa1, (char)0xe4, (char)0xb9, (char)0x12, (char)0x6b, (char)0x05, (char)0x3e, (char)0x83, (char)0x99, (char)0x49, (char)0xbf, (char)0x66, (char)0xbb, (char)0xf6, (char)0x76, (char)0xd3, (char)0xa9, (char)0x24, (char)0x61, (char)0x8c, (char)0x25, (char)0x49, (char)0xd0, (char)0xf7, (char)0x83, (char)0x44, (char)0xfb, (char)0x27, (char)0xe2, (char)0x7d, (char)0x69, (char)0x6d, (char)0x34, (char)0x67, (char)0xed, (char)0x39, (char)0x89, (char)0x02, (char)0xcb, (char)0x2f, (char)0x33, (char)0x3c, (char)0xcd, (char)0x12, (char)0x42, (char)0x8f, (char)0x86, (char)0x7d, (char)0xda, (char)0x3f, (char)0xd7, (char)0x26, (char)0x62, (char)0x9c, (char)0x1f, (char)0x2e, (char)0xa8, (char)0xc3, (char)0x85, (char)0xf1, (char)0x73, (char)0xe5, (char)0x2c, (char)0x11, (char)0xde, (char)0x98, (char)0xc8, (char)0xb0, (char)0x10, (char)0x17, (char)0x55, (char)0xf5, (char)0x32, (char)0x52, (char)0x67, (char)0xca, (char)0x64, (char)0x50, (char)0x28, (char)0x9a, (char)0x24, (char)0x92, (char)0xa1, (char)0x97, (char)0x57, (char)0x81, (char)0xaf, (char)0xca, (char)0x1e, (char)0xc0, (char)0xa4, (char)0x71, (char)0x2d, (char)0x2a, (char)0xec, (char)0xc9, (char)0x23, (char)0x6a, (char)0x0c, (char)0x1d, (char)0x54, (char)0x15, (char)0x2a, (char)0x56, (char)0x42, (char)0x0a, (char)0x83, (char)0xff, (char)0x28, (char)0xba, (char)0xe7, (char)0x68, (char)0x38, (char)0xf5, (char)0x32, (char)0xa9, (char)0xb7, (char)0xe7, (char)0x70, (char)0x32, (char)0xa8, (char)0x79, (char)0x5e, (char)0x46, (char)0x1d, (char)0xec, (char)0x29, (char)0x8a, (char)0xde, (char)0x41, (char)0x94, (char)0x94, (char)0x26, (char)0x79, (char)0xc2, (char)0x52, (char)0x23, (char)0xe0, (char)0xa1, (char)0x1d, (char)0x65, (char)0x0c, (char)0xbe, (char)0x1b, (char)0x87, (char)0x2a, (char)0x21, (char)0x53, (char)0x2f, (char)0x35, (char)0x56, (char)0xe8, (char)0xd1, (char)0x7b, (char)0xb8, (char)0x23, (char)0x75, (char)0x56, (char)0xc7, (char)0x08, (char)0x9d, (char)0x13, (char)0xf0, (char)0x8f, (char)0x80, (char)0x38, (char)0xe9, (char)0x92, (char)0xf7, (char)0x16, (char)0xc2, (char)0xf3, (char)0x74, (char)0xa7, (char)0x92, (char)0xf5, (char)0x49, (char)0x7d, (char)0x09, (char)0x41, (char)0xbc, (char)0x07, (char)0x61, (char)0x1f, (char)0xe6, (char)0xa0, (char)0xd8, (char)0xa6, (char)0xe3, (char)0x72, (char)0xa4, (char)0x59, (char)0x4a, (char)0xd9, (char)0x33, (char)0x40, (char)0x80, (char)0x3a, (char)0x3a, (char)0xb3, (char)0xa0, (char)0x96, (char)0xca, (char)0x56, (char)0x98, (char)0xbd, (char)0x1f, (char)0x80, (char)0x86, (char)0x6c, (char)0xe1, (char)0x09, (char)0x64, (char)0x1b, (char)0x1a, (char)0xc9, (char)0x52, (char)0xaa, (char)0xd1, (char)0x39, (char)0xea, (char)0x4b, (char)0x6a, (char)0x3e, (char)0x4e, (char)0xa4, (char)0xea, (char)0x00, (char)0xde, (char)0x07, (char)0x0b, (char)0x23, (char)0xbc, (char)0x40, (char)0xc4, (char)0xd2, (char)0xd9, (char)0xf6, (char)0xda, (char)0x8e, (char)0x22, (char)0x36, (char)0xbe, (char)0x5e, (char)0x65, (char)0x6e, (char)0xbe, (char)0xc8, (char)0xb0, (char)0x07, (char)0xa2, (char)0x2d, (char)0xe9, (char)0x4b, (char)0x73, (char)0x54, (char)0xe6, (char)0x0a, (char)0xf2, (char)0xd3, (char)0x83, (char)0x8b, (char)0x27, (char)0x4c, (char)0xcc, (char)0x0c, (char)0x8a, (char)0xd4, (char)0x2b, (char)0xb8, (char)0x95, (char)0x2e, (char)0x42, (char)0x64, (char)0x29, (char)0xc1, (char)0xe0, (char)0x6b, (char)0x92, (char)0xab, (char)0xfe, (char)0x53, (char)0x06, (char)0x96, (char)0x4a, (char)0x8c, (char)0x5d, (char)0x7c, (char)0x51, (char)0x74, (char)0xd0, (char)0x1e, (char)0x37, (char)0x35, (char)0x9c, (char)0x1e, (char)0x69, (char)0x8f, (char)0x68, (char)0x18, (char)0xd9, (char)0xbe, (char)0xaf, (char)0x81, (char)0x9b, (char)0x7e, (char)0xd8, (char)0x71, (char)0x9d, (char)0xb6, (char)0x50, (char)0x43, (char)0x78, (char)0x85, (char)0x7d, (char)0x65, (char)0x93, (char)0x45, (char)0xb4, (char)0x02, (char)0xd0, (char)0x5c, (char)0x36, (char)0xe2, (char)0x62, (char)0x3f, (char)0x40, (char)0x33, (char)0xee, (char)0x91, (char)0xe5, (char)0x3f, (char)0x67, (char)0x39, (char)0x2f, (char)0x1b, (char)0x89, (char)0x9f, (char)0x04, (char)0x9d, (char)0x46, (char)0x3e, (char)0x70, (char)0x92, (char)0x9e, (char)0x8c, (char)0xf5
    };
    char s0s1s2[] = {
        (char)0x03, (char)0xac, (char)0x44, (char)0x29, (char)0x53, (char)0x04, (char)0x05, (char)0x00, (char)0x01, (char)0x6e, (char)0x65, (char)0x69, (char)0x2d, (char)0x69, (char)0x2d, (char)0x69, (char)0x73, (char)0x6e, (char)0x69, (char)0x73, (char)0x6c, (char)0x65, (char)0x72, (char)0x69, (char)0x72, (char)0x76, (char)0x65, (char)0x72, (char)0x69, (char)0x77, (char)0x74, (char)0x2e, (char)0x6e, (char)0x72, (char)0x76, (char)0x72, (char)0x65, (char)0x72, (char)0x70, (char)0x72, (char)0x69, (char)0x69, (char)0x70, (char)0x72, (char)0x73, (char)0x6e, (char)0x65, (char)0x72, (char)0x72, (char)0x6e, (char)0x2d, (char)0x65, (char)0x74, (char)0x72, (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x40, (char)0x69, (char)0x69, (char)0x76, (char)0x77, (char)0x2d, (char)0x73, (char)0x65, (char)0x72, (char)0x72, (char)0x76, (char)0x73, (char)0x72, (char)0x2e, (char)0x2d, (char)0x76, (char)0x65, (char)0x31, (char)0x65, (char)0x6d, (char)0x6d, (char)0x73, (char)0x69, (char)0x73, (char)0x74, (char)0x2e, (char)0x74, (char)0x72, (char)0x65, (char)0x65, (char)0x72, (char)0x65, (char)0x2d, (char)0x74, (char)0x69, (char)0x31, (char)0x65, (char)0x2d, (char)0x6f, (char)0x77, (char)0x2e, (char)0x76, (char)0x77, (char)0x2d, (char)0x77, (char)0x72, (char)0x65, (char)0x65, (char)0x31, (char)0x74, (char)0x73, (char)0x70, (char)0x74, (char)0x6e, (char)0x72, (char)0x6e, (char)0x73, (char)0x6d, (char)0x2e, (char)0x69, (char)0x72, (char)0x2d, (char)0x65, (char)0x69, (char)0x77, (char)0x69, (char)0x76, (char)0x72, (char)0x77, (char)0x72, (char)0x32, (char)0x6e, (char)0x65, (char)0x6c, (char)0x2e, (char)0x2d, (char)0x6e, (char)0x69, (char)0x6d, (char)0x6c, (char)0x73, (char)0x65, (char)0x73, (char)0x70, (char)0x2d, (char)0x65, (char)0x72, (char)0x40, (char)0x72, (char)0x74, (char)0x6e, (char)0x6e, (char)0x6d, (char)0x6f, (char)0x70, (char)0x74, (char)0x73, (char)0x2d, (char)0x63, (char)0x69, (char)0x32, (char)0x31, (char)0x2d, (char)0x40, (char)0x69, (char)0x70, (char)0x2d, (char)0x2d, (char)0x72, (char)0x69, (char)0x74, (char)0x63, (char)0x6f, (char)0x69, (char)0x69, (char)0x65, (char)0x6e, (char)0x32, (char)0x6f, (char)0x6c, (char)0x6e, (char)0x72, (char)0x73, (char)0x77, (char)0x65, (char)0x65, (char)0x72, (char)0x32, (char)0x6d, (char)0x65, (char)0x6c, (char)0x2d, (char)0x72, (char)0x6e, (char)0x65, (char)0x6d, (char)0x31, (char)0x65, (char)0x74, (char)0x2d, (char)0x6f, (char)0x72, (char)0x65, (char)0x63, (char)0x69, (char)0x40, (char)0x70, (char)0x2d, (char)0x65, (char)0x6d, (char)0x2d, (char)0x77, (char)0x63, (char)0x63, (char)0x74, (char)0x40, (char)0x36, (char)0x2d, (char)0x72, (char)0x65, (char)0x70, (char)0x2d, (char)0x6e, (char)0x69, (char)0x6d, (char)0x65, (char)0x74, (char)0x70, (char)0x76, (char)0x40, (char)0x76, (char)0x72, (char)0x72, (char)0x69, (char)0x77, (char)0x76, (char)0x69, (char)0x74, (char)0x74, (char)0x65, (char)0x31, (char)0x6d, (char)0x2e, (char)0x6f, (char)0x72, (char)0x73, (char)0x73, (char)0x6c, (char)0x40, (char)0x36, (char)0x72, (char)0x70, (char)0x72, (char)0x70, (char)0x72, (char)0x69, (char)0x32, (char)0x6c, (char)0x77, (char)0x70, (char)0x76, (char)0x65, (char)0x72, (char)0x76, (char)0x63, (char)0x65, (char)0x65, (char)0x77, (char)0x72, (char)0x6e, (char)0x2e, (char)0x76, (char)0x69, (char)0x69, (char)0x2e, (char)0x40, (char)0x72, (char)0x2e, (char)0x2e, (char)0x72, (char)0x73, (char)0x6e, (char)0x72, (char)0x72, (char)0x6e, (char)0x70, (char)0x40, (char)0x77, (char)0x65, (char)0x77, (char)0x65, (char)0x70, (char)0x63, (char)0x74, (char)0x2d, (char)0x70, (char)0x72, (char)0x2d, (char)0x74, (char)0x72, (char)0x31, (char)0x65, (char)0x6e, (char)0x2d, (char)0x76, (char)0x2d, (char)0x2d, (char)0x2d, (char)0x74, (char)0x76, (char)0x2d, (char)0x74, (char)0x65, (char)0x2e, (char)0x2d, (char)0x6c, (char)0x76, (char)0x2d, (char)0x6c, (char)0x70, (char)0x73, (char)0x6d, (char)0x65, (char)0x72, (char)0x31, (char)0x31, (char)0x36, (char)0x76, (char)0x73, (char)0x73, (char)0x6e, (char)0x2d, (char)0x6e, (char)0x73, (char)0x72, (char)0x2d, (char)0x6f, (char)0x6c, (char)0x65, (char)0x74, (char)0x77, (char)0x65, (char)0x69, (char)0x72, (char)0x69, (char)0x65, (char)0x6d, (char)0x76, (char)0x31, (char)0x65, (char)0x73, (char)0x72, (char)0x6c, (char)0x72, (char)0x77, (char)0x65, (char)0x76, (char)0x74, (char)0x72, (char)0x69, (char)0x72, (char)0x76, (char)0x32, (char)0x73, (char)0x6d, (char)0x72, (char)0x2d, (char)0x6d, (char)0x40, (char)0x69, (char)0x40, (char)0x69, (char)0x31, (char)0x69, (char)0x6f, (char)0x6e, (char)0x6d, (char)0x69, (char)0x73, (char)0x70, (char)0x72, (char)0x77, (char)0x6f, (char)0x6f, (char)0x65, (char)0x77, (char)0x76, (char)0x70, (char)0x70, (char)0x6c, (char)0x6f, (char)0x72, (char)0x65, (char)0x32, (char)0x36, (char)0x6c, (char)0x74, (char)0x6e, (char)0x72, (char)0x74, (char)0x2d, (char)0x6e, (char)0x6c, (char)0x72, (char)0x72, (char)0x2d, (char)0x74, (char)0x65, (char)0x73, (char)0x70, (char)0x65, (char)0x72, (char)0x6c, (char)0x65, (char)0x65, (char)0x2d, (char)0x6e, (char)0x70, (char)0x6e, (char)0x40, (char)0x65, (char)0x6e, (char)0x6e, (char)0x74, (char)0x65, (char)0x6e, (char)0x72, (char)0x6e, (char)0xfe, (char)0x5a, (char)0x38, (char)0x79, (char)0x81, (char)0xe8, (char)0x49, (char)0xee, (char)0x93, (char)0xbb, (char)0xa0, (char)0x59, (char)0x4a, (char)0xa0, (char)0xcc, (char)0x31, (char)0xbf, (char)0x0d, (char)0x86, (char)0xc0, (char)0x3f, (char)0xae, (char)0x2a, (char)0x16, (char)0xfa, (char)0xf0, (char)0x4e, (char)0x0f, (char)0xa3, (char)0x01, (char)0x06, (char)0xa0, (char)0x0e, (char)0xa5, (char)0x8c, (char)0xa4, (char)0xca, (char)0xd2, (char)0x01, (char)0xa5, (char)0x90, (char)0xbd, (char)0x55, (char)0xd1, (char)0x42, (char)0x2b, (char)0xd4, (char)0xb3, (char)0xbb, (char)0x06, (char)0xb1, (char)0x3a, (char)0x94, (char)0x41, (char)0x76, (char)0x1d, (char)0xa5, (char)0x23, (char)0x6e, (char)0x1e, (char)0x59, (char)0x73, (char)0x63, (char)0x34, (char)0x60, (char)0xd3, (char)0x48, (char)0xc0, (char)0x3b, (char)0xcf, (char)0xf1, (char)0xa8, (char)0x38, (char)0xd6, (char)0xf3, (char)0x5e, (char)0x6d, (char)0xcb, (char)0xea, (char)0xfc, (char)0x9c, (char)0x52, (char)0xae, (char)0x9a, (char)0x89, (char)0xdb, (char)0x24, (char)0x1b, (char)0x92, (char)0x4a, (char)0x85, (char)0x97, (char)0x3c, (char)0xd8, (char)0x4c, (char)0x31, (char)0xad, (char)0xfd, (char)0x00, (char)0xef, (char)0xc5, (char)0x17, (char)0xa5, (char)0x22, (char)0xc0, (char)0xf1, (char)0x94, (char)0x18, (char)0xec, (char)0xf6, (char)0x49, (char)0xe5, (char)0x05, (char)0x11, (char)0x12, (char)0x67, (char)0x6c, (char)0x71, (char)0xc0, (char)0x84, (char)0x6d, (char)0x50, (char)0xf8, (char)0x23, (char)0x01, (char)0x57, (char)0xc4, (char)0xfc, (char)0x73, (char)0x65, (char)0x69, (char)0x6e, (char)0x65, (char)0x72, (char)0x6d, (char)0x6f, (char)0x69, (char)0x2d, (char)0x65, (char)0x65, (char)0x69, (char)0x63, (char)0x63, (char)0x69, (char)0x2d, (char)0x72, (char)0x2d, (char)0x69, (char)0x2d, (char)0x2d, (char)0x77, (char)0x72, (char)0x76, (char)0x72, (char)0x72, (char)0x2d, (char)0x76, (char)0x70, (char)0x63, (char)0x69, (char)0x74, (char)0x73, (char)0x6d, (char)0x65, (char)0x6c, (char)0x2d, (char)0x73, (char)0x6c, (char)0x65, (char)0x6e, (char)0x73, (char)0x77, (char)0x69, (char)0x63, (char)0x69, (char)0x70, (char)0x31, (char)0x40, (char)0x72, (char)0x69, (char)0x2d, (char)0x2d, (char)0x2d, (char)0x72, (char)0x72, (char)0x6c, (char)0x72, (char)0x63, (char)0x72, (char)0x77, (char)0x6e, (char)0x6c, (char)0x2d, (char)0x72, (char)0x2e, (char)0x76, (char)0x72, (char)0x65, (char)0x6d, (char)0x76, (char)0x36, (char)0x6d, (char)0x72, (char)0x77, (char)0x72, (char)0x65, (char)0x65, (char)0x69, (char)0x72, (char)0x76, (char)0x6d, (char)0x76, (char)0x74, (char)0x76, (char)0x72, (char)0x65, (char)0x69, (char)0x72, (char)0x6e, (char)0x6d, (char)0x77, (char)0x6c, (char)0x40, (char)0x32, (char)0x70, (char)0x65, (char)0x65, (char)0x69, (char)0x72, (char)0x31, (char)0x2e, (char)0x70, (char)0x36, (char)0x31, (char)0x65, (char)0x70, (char)0x72, (char)0x72, (char)0x73, (char)0x72, (char)0x6e, (char)0x6e, (char)0x73, (char)0x32, (char)0x2d, (char)0x2d, (char)0x2d, (char)0x69, (char)0x65, (char)0x31, (char)0x74, (char)0x6e, (char)0x65, (char)0x74, (char)0x65, (char)0x76, (char)0x69, (char)0x6d, (char)0x6c, (char)0x6e, (char)0x70, (char)0x74, (char)0x73, (char)0x72, (char)0x6d, (char)0x72, (char)0x72, (char)0x69, (char)0x65, (char)0x74, (char)0x65, (char)0x65, (char)0x2d, (char)0x70, (char)0x74, (char)0x6e, (char)0x74, (char)0x65, (char)0x6f, (char)0x72, (char)0x69, (char)0x76, (char)0x40, (char)0x31, (char)0x69, (char)0x72, (char)0x6d, (char)0x6d, (char)0x77, (char)0x69, (char)0x72, (char)0x65, (char)0x6e, (char)0x40, (char)0x63, (char)0x40, (char)0x65, (char)0x65, (char)0x69, (char)0x2d, (char)0x72, (char)0x65, (char)0x40, (char)0x69, (char)0x32, (char)0x74, (char)0x73, (char)0x6e, (char)0x36, (char)0x2d, (char)0x70, (char)0x65, (char)0x6c, (char)0x70, (char)0x6e, (char)0x72, (char)0x69, (char)0x32, (char)0x65, (char)0x74, (char)0x76, (char)0x77, (char)0x73, (char)0x6f, (char)0x77, (char)0x65, (char)0x72, (char)0x2d, (char)0x6e, (char)0x73, (char)0x65, (char)0x65, (char)0x70, (char)0x65, (char)0x2d, (char)0x65, (char)0x73, (char)0x2d, (char)0x65, (char)0x2e, (char)0x73, (char)0x69, (char)0x67, (char)0x45, (char)0x8b, (char)0x6b, (char)0x3b, (char)0xc9, (char)0x5f, (char)0x09, (char)0x65, (char)0x65, (char)0x72, (char)0x6c, (char)0x73, (char)0x6d, (char)0x70, (char)0x70, (char)0x73, (char)0x63, (char)0x70, (char)0x40, (char)0x72, (char)0x76, (char)0x65, (char)0x6e, (char)0x6f, (char)0x6c, (char)0x69, (char)0x2e, (char)0x72, (char)0x73, (char)0x76, (char)0x69, (char)0x77, (char)0x72, (char)0x2d, (char)0x69, (char)0x6e, (char)0x69, (char)0x65, (char)0x77, (char)0x73, (char)0x69, (char)0x70, (char)0x77, (char)0x63, (char)0x65, (char)0x74, (char)0x72, (char)0x73, (char)0x31, (char)0x65, (char)0x65, (char)0x72, (char)0x76, (char)0x69, (char)0x65, (char)0x77, (char)0x6d, (char)0x65, (char)0x36, (char)0x6e, (char)0x6e, (char)0x69, (char)0x6d, (char)0x6e, (char)0x70, (char)0x77, (char)0x72, (char)0x65, (char)0x31, (char)0x65, (char)0x6e, (char)0x6e, (char)0x65, (char)0x2d, (char)0x65, (char)0x65, (char)0x2e, (char)0x77, (char)0x6e, (char)0x6f, (char)0x2d, (char)0x76, (char)0x65, (char)0x72, (char)0x6c, (char)0x31, (char)0x76, (char)0x65, (char)0x72, (char)0x2d, (char)0x36, (char)0x6c, (char)0x70, (char)0x6f, (char)0x65, (char)0x72, (char)0x73, (char)0x63, (char)0x72, (char)0x77, (char)0x73, (char)0x72, (char)0x65, (char)0x65, (char)0x65, (char)0x6c, (char)0x76, (char)0x72, (char)0x65, (char)0x6e, (char)0x65, (char)0x2e, (char)0x6f, (char)0x2d, (char)0x72, (char)0x70, (char)0x65, (char)0x74, (char)0x72,
        (char)0x77, (char)0x69, (char)0x69, (char)0x72, (char)0x65, (char)0x77, (char)0x6c, (char)0x72, (char)0x2d, (char)0x69, (char)0x72, (char)0x31, (char)0x6e, (char)0x65, (char)0x70, (char)0x72, (char)0x74, (char)0x76, (char)0x6c, (char)0x2e, (char)0x72, (char)0x65, (char)0x72, (char)0x6c, (char)0x73, (char)0x6c, (char)0x2e, (char)0x2e, (char)0x72, (char)0x2d, (char)0x6e, (char)0x63, (char)0x32, (char)0x2e, (char)0x65, (char)0x2d, (char)0x65, (char)0x69, (char)0x2d, (char)0x65, (char)0x70, (char)0x6e, (char)0x72, (char)0x72, (char)0x32, (char)0x2e, (char)0x73, (char)0x70, (char)0x77, (char)0x65, (char)0x73, (char)0x77, (char)0x73, (char)0x40, (char)0x40, (char)0x73, (char)0x63, (char)0x2e, (char)0x65, (char)0x76, (char)0x70, (char)0x65, (char)0x69, (char)0x65, (char)0x70, (char)0x73, (char)0x40, (char)0x65, (char)0x73, (char)0x2d, (char)0x2d, (char)0x2e, (char)0x2e, (char)0x73, (char)0x65, (char)0x6f, (char)0x65, (char)0x65, (char)0x6d, (char)0x76, (char)0x70, (char)0x6d, (char)0x69, (char)0x70, (char)0x70, (char)0x69, (char)0x2e, (char)0x76, (char)0x6e, (char)0x72, (char)0x72, (char)0x72, (char)0x6d, (char)0x73, (char)0x6f, (char)0x73, (char)0x72, (char)0x72, (char)0x72, (char)0x77, (char)0x70, (char)0x65, (char)0x69, (char)0x72, (char)0x73, (char)0x6e, (char)0x69, (char)0x65, (char)0x65, (char)0x74, (char)0x65, (char)0x69, (char)0x40, (char)0x63, (char)0x69, (char)0x70, (char)0x6c, (char)0x6e, (char)0x2d, (char)0x65, (char)0x69, (char)0x72, (char)0x63, (char)0x6c, (char)0x72, (char)0x2e, (char)0x36, (char)0x69, (char)0x72, (char)0x6c, (char)0x6c, (char)0x2d, (char)0x6f, (char)0x76, (char)0x69, (char)0x6f, (char)0x2d, (char)0x6d, (char)0x6c, (char)0x72, (char)0x72, (char)0x2e, (char)0x70, (char)0x73, (char)0x6d, (char)0x6f, (char)0x2e, (char)0x6e, (char)0x69, (char)0x65, (char)0x65, (char)0x2d, (char)0x6d, (char)0x76, (char)0x6e, (char)0x69, (char)0x73, (char)0x73, (char)0x73, (char)0x74, (char)0x63, (char)0x65, (char)0x76, (char)0x2e, (char)0x77, (char)0x2d, (char)0x36, (char)0x73, (char)0x69, (char)0x2d, (char)0x72, (char)0x72, (char)0x6c, (char)0x36, (char)0x74, (char)0x72, (char)0x6d, (char)0x65, (char)0x2d, (char)0x65, (char)0x2e, (char)0x6d, (char)0x31, (char)0x72, (char)0x6f, (char)0x74, (char)0x76, (char)0x31, (char)0x65, (char)0x6d, (char)0x69, (char)0x72, (char)0x69, (char)0x69, (char)0x2d, (char)0x72, (char)0x73, (char)0x72, (char)0x72, (char)0x76, (char)0x31, (char)0x6e, (char)0x2d, (char)0x69, (char)0x6e, (char)0x77, (char)0x70, (char)0x69, (char)0x72, (char)0x6e, (char)0x76, (char)0x74, (char)0x6f, (char)0x65, (char)0x63, (char)0x6f, (char)0x73, (char)0x65, (char)0x73, (char)0x72, (char)0x69, (char)0x69, (char)0x40, (char)0x6e, (char)0x65, (char)0x65, (char)0x65, (char)0x65, (char)0x77, (char)0x70, (char)0x70, (char)0x6e, (char)0x72, (char)0x6e, (char)0x65, (char)0x72, (char)0x32, (char)0x65, (char)0x2d, (char)0x77, (char)0x69, (char)0x6e, (char)0x70, (char)0x69, (char)0x6f, (char)0x76, (char)0x77, (char)0x72, (char)0x74, (char)0x77, (char)0x6e, (char)0x72, (char)0xfe, (char)0x98, (char)0xf3, (char)0xb4, (char)0xff, (char)0x3f, (char)0x2e, (char)0xdb, (char)0x59, (char)0xbd, (char)0x32, (char)0x02, (char)0x6a, (char)0x44, (char)0x03, (char)0x67, (char)0x9e, (char)0xe1, (char)0x98, (char)0x97, (char)0xed, (char)0x67, (char)0x6d, (char)0xb0, (char)0x8f, (char)0xa9, (char)0xb6, (char)0xf8, (char)0x4d, (char)0x92, (char)0x35, (char)0x19, (char)0x72, (char)0x72, (char)0x65, (char)0x74, (char)0x73, (char)0x6e, (char)0x65, (char)0x65, (char)0x69, (char)0x36, (char)0x72, (char)0x73, (char)0x2d, (char)0x70, (char)0x2d, (char)0x2d, (char)0x69, (char)0x6e, (char)0x72, (char)0x65, (char)0x32, (char)0x72, (char)0x77, (char)0x72, (char)0x73, (char)0x77, (char)0x73, (char)0x70, (char)0x2d, (char)0x2d, (char)0x69, (char)0x6c, (char)0x70, (char)0x74, (char)0x65, (char)0x69, (char)0x72, (char)0x74, (char)0x6e, (char)0x76, (char)0x65, (char)0x76, (char)0x76, (char)0x69, (char)0x69, (char)0x65, (char)0x70, (char)0x6e, (char)0x73, (char)0x6e, (char)0x36, (char)0x76, (char)0x70, (char)0x76, (char)0x6c, (char)0x6c, (char)0x70, (char)0x6e, (char)0x6e, (char)0x74, (char)0x2e, (char)0x6f, (char)0x32, (char)0x74, (char)0x76, (char)0x74, (char)0x40, (char)0x72, (char)0x6e, (char)0x72, (char)0x74, (char)0x74, (char)0x2d, (char)0x6f, (char)0x72, (char)0x73, (char)0x32, (char)0x72, (char)0x32, (char)0x72, (char)0x70, (char)0x65, (char)0x65, (char)0x6e, (char)0x72, (char)0x70, (char)0x73, (char)0x72, (char)0x69, (char)0x74, (char)0x74, (char)0x6e, (char)0x72, (char)0x6c, (char)0x31, (char)0x74, (char)0x77, (char)0x31, (char)0x63, (char)0x63, (char)0x74, (char)0x69, (char)0x72, (char)0x69, (char)0x72, (char)0x70, (char)0x31, (char)0x74, (char)0x72, (char)0x76, (char)0x65, (char)0x72, (char)0x65, (char)0x6c, (char)0x76, (char)0x6d, (char)0x72, (char)0x6c, (char)0x69, (char)0x72, (char)0x65, (char)0x76, (char)0x69, (char)0x6f, (char)0x69, (char)0x6c, (char)0x74, (char)0x6e, (char)0x65, (char)0x69, (char)0x77, (char)0x73, (char)0x70, (char)0x69, (char)0x72, (char)0x2d, (char)0x65, (char)0x74, (char)0x2e, (char)0x65, (char)0x65, (char)0x6d, (char)0x72, (char)0x31, (char)0x2d, (char)0x72, (char)0x36, (char)0x65, (char)0x2d, (char)0x69, (char)0x6d, (char)0x36, (char)0x6e, (char)0x72, (char)0x6d, (char)0x6c, (char)0x72, (char)0x72, (char)0x65, (char)0x65, (char)0x6e, (char)0x31, (char)0x6e, (char)0x40, (char)0x72, (char)0x40, (char)0x6f, (char)0x73, (char)0x6d, (char)0x36, (char)0x2e, (char)0x72, (char)0x65, (char)0x36, (char)0x74, (char)0x77, (char)0x65, (char)0x65, (char)0x73, (char)0x36, (char)0x76, (char)0x6c, (char)0x6f, (char)0x2d, (char)0x36, (char)0x6d, (char)0x36, (char)0x70, (char)0x32, (char)0x74, (char)0x6d, (char)0x65, (char)0x6d, (char)0x69, (char)0x65, (char)0x65, (char)0x69, (char)0x76, (char)0x69, (char)0x74, (char)0x2d, (char)0x63, (char)0x2d, (char)0x6e, (char)0x32, (char)0x72, (char)0x63, (char)0x2d, (char)0x77, (char)0x72, (char)0x74, (char)0x72, (char)0x70, (char)0x6e, (char)0x76, (char)0x6f, (char)0x72, (char)0x40, (char)0x65, (char)0x65, (char)0x6d, (char)0x77, (char)0x2d, (char)0x2d, (char)0x74, (char)0x6e, (char)0x73, (char)0x76, (char)0x65, (char)0x69, (char)0x69, (char)0x72, (char)0x6f, (char)0x65, (char)0x70, (char)0x69, (char)0x6d, (char)0x76, (char)0x69, (char)0x65, (char)0x72, (char)0x2d, (char)0x74, (char)0x2d, (char)0x69, (char)0x65, (char)0x72, (char)0x69, (char)0x6f, (char)0x72, (char)0x72, (char)0x69, (char)0x76, (char)0x72, (char)0x77, (char)0x69, (char)0x2e, (char)0x77, (char)0x69, (char)0x70, (char)0x69, (char)0x6d, (char)0x36, (char)0x72, (char)0x76, (char)0x65, (char)0x76, (char)0x73, (char)0x6e, (char)0x72, (char)0x65, (char)0x2e, (char)0x76, (char)0x2d, (char)0x76, (char)0x6f, (char)0x2d, (char)0x65, (char)0x73, (char)0x72, (char)0x74, (char)0x36, (char)0x2d, (char)0x6f, (char)0x70, (char)0x73, (char)0x74, (char)0x74, (char)0x77, (char)0x6c, (char)0x2d, (char)0x65, (char)0x72, (char)0x6e, (char)0x65, (char)0x6c, (char)0x72, (char)0x32, (char)0x2d, (char)0x72, (char)0x69, (char)0x6d, (char)0x6e, (char)0x72, (char)0x6c, (char)0x6f, (char)0x65, (char)0x36, (char)0x31, (char)0x65, (char)0x65, (char)0x69, (char)0x73, (char)0x31, (char)0x74, (char)0x69, (char)0x69, (char)0x65, (char)0x40, (char)0x69, (char)0x6e, (char)0x2d, (char)0x63, (char)0x40, (char)0x31, (char)0x70, (char)0x65, (char)0x6e, (char)0x2d, (char)0x69, (char)0x72, (char)0x65, (char)0x65, (char)0x76, (char)0x65, (char)0x70, (char)0x72, (char)0x6c, (char)0x2d, (char)0x6e, (char)0x73, (char)0x69, (char)0x65, (char)0x65, (char)0x6e, (char)0x2e, (char)0x63, (char)0x6c, (char)0x72, (char)0x65, (char)0x2d, (char)0x2e, (char)0x6d, (char)0x72, (char)0x76, (char)0x70, (char)0x69, (char)0x6d, (char)0x40, (char)0x32, (char)0x77, (char)0x72, (char)0x6e, (char)0x72, (char)0x6c, (char)0x36, (char)0x72, (char)0x31, (char)0x2d, (char)0x73, (char)0x74, (char)0x2d, (char)0x69, (char)0x63, (char)0x40, (char)0x70, (char)0x32, (char)0x65, (char)0x31, (char)0x69, (char)0x69, (char)0x65, (char)0x72, (char)0x63, (char)0x74, (char)0x72, (char)0x74, (char)0x77, (char)0x6e, (char)0x69, (char)0x72, (char)0x65, (char)0x76, (char)0x65, (char)0x77, (char)0x69, (char)0x69, (char)0x73, (char)0x6e, (char)0x77, (char)0x77, (char)0x73, (char)0x6f, (char)0x69, (char)0x70, (char)0x73, (char)0x2d, (char)0x65, (char)0x65, (char)0x73, (char)0x65, (char)0x77, (char)0x2d, (char)0x73, (char)0x72, (char)0x6d, (char)0x65, (char)0x32, (char)0x6e, (char)0x73, (char)0x36, (char)0x65, (char)0x72, (char)0x77, (char)0x70, (char)0x65, (char)0x69, (char)0x2d, (char)0x2d, (char)0x74, (char)0x6f, (char)0x6f, (char)0x36, (char)0x63, (char)0x74, (char)0x72, (char)0x63, (char)0x77, (char)0x69, (char)0x2e, (char)0x31, (char)0x6c, (char)0x65, (char)0x77, (char)0x72, (char)0x65, (char)0x76, (char)0x74, (char)0x2d, (char)0x77, (char)0x2e, (char)0x76, (char)0x72, (char)0x6e, (char)0x36, (char)0x70, (char)0x69, (char)0x2e, (char)0x6e, (char)0x72, (char)0x77, (char)0x69, (char)0x65, (char)0x74, (char)0x2d, (char)0x6e, (char)0x63, (char)0x6e, (char)0x70, (char)0x2d, (char)0x6e, (char)0x2e, (char)0x6d, (char)0x69, (char)0x65, (char)0x63, (char)0x65, (char)0x2d, (char)0x76, (char)0x70, (char)0x73, (char)0x31, (char)0x73, (char)0x2d, (char)0x76, (char)0x6e, (char)0x6e, (char)0x6c, (char)0x2d, (char)0x6c, (char)0x2d, (char)0x65, (char)0x6e, (char)0x73, (char)0x6c, (char)0x65, (char)0x74, (char)0x70, (char)0x65, (char)0x2d, (char)0x6e, (char)0x77, (char)0x76, (char)0x40, (char)0x69, (char)0x40, (char)0x63, (char)0x6f, (char)0x72, (char)0x32, (char)0x6d, (char)0x31, (char)0x72, (char)0x36, (char)0x69, (char)0x73, (char)0x72, (char)0x70, (char)0x65, (char)0x2d, (char)0x6c, (char)0x2e, (char)0x72, (char)0x74, (char)0x74, (char)0x65, (char)0x69, (char)0x6f, (char)0x69, (char)0x2d, (char)0x2d, (char)0x65, (char)0x6f, (char)0x65, (char)0x74, (char)0x72, (char)0x69, (char)0x76, (char)0x72, (char)0x72, (char)0x65, (char)0x69, (char)0x76, (char)0x69, (char)0x69, (char)0x6e, (char)0x31, (char)0x65, (char)0x76, (char)0x72, (char)0x73, (char)0x77, (char)0x72, (char)0x2d, (char)0x69, (char)0x65, (char)0x69, (char)0x70, (char)0x65, (char)0x6e, (char)0x6e, (char)0x65, (char)0x65, (char)0x6e, (char)0x2d, (char)0x72, (char)0x76, (char)0x72, (char)0x6c, (char)0x2e, (char)0x70, (char)0x76, (char)0x6e, (char)0x69, (char)0x72, (char)0x70, (char)0x73, (char)0x2d, (char)0x69, (char)0x74, (char)0x76, (char)0x72, (char)0x70, (char)0x65, (char)0x63, (char)0x72, (char)0x70, (char)0x6e, (char)0x36, (char)0x6c, (char)0x74, (char)0x72, (char)0x72, (char)0x72, (char)0x73, (char)0x65, (char)0x40, (char)0x63, (char)0x6d, (char)0x63, (char)0x32, (char)0x65, (char)0x32, (char)0x69, (char)0x6e,
        (char)0x77, (char)0x65, (char)0x74, (char)0x72, (char)0x77, (char)0x40, (char)0x69, (char)0x65, (char)0x70, (char)0x31, (char)0x36, (char)0x72, (char)0x73, (char)0x2d, (char)0x72, (char)0x72, (char)0x32, (char)0x72, (char)0x6c, (char)0x77, (char)0x6e, (char)0x6f, (char)0x77, (char)0x6c, (char)0x74, (char)0x72, (char)0x2d, (char)0x6e, (char)0x65, (char)0x70, (char)0x6c, (char)0x72, (char)0x6f, (char)0x69, (char)0x2d, (char)0x2d, (char)0x69, (char)0x36, (char)0x69, (char)0x69, (char)0x76, (char)0x69, (char)0x69, (char)0x6d, (char)0x72, (char)0x73, (char)0x6f, (char)0x6d, (char)0x74, (char)0x70, (char)0x76, (char)0x6d, (char)0x6d, (char)0x69, (char)0x72, (char)0x70, (char)0x70, (char)0x2d, (char)0x31, (char)0x63, (char)0x6c, (char)0x65, (char)0x65, (char)0x6e, (char)0x2d, (char)0x77, (char)0x74, (char)0x73, (char)0x6c, (char)0x72, (char)0x6e, (char)0x65, (char)0x65, (char)0x2d, (char)0x6c, (char)0x69, (char)0x2d, (char)0x6e, (char)0x74, (char)0x70, (char)0x72, (char)0x77, (char)0x77, (char)0x65, (char)0x65, (char)0x65, (char)0x2d, (char)0x76, (char)0x6e, (char)0x72, (char)0x69, (char)0x69, (char)0x73, (char)0x65, (char)0x74, (char)0x73, (char)0x76, (char)0x72, (char)0x72, (char)0x72, (char)0x69, (char)0x72, (char)0x73, (char)0x72, (char)0x6f, (char)0x2e, (char)0x77, (char)0x2d, (char)0x2d, (char)0x6c, (char)0x6e, (char)0x65, (char)0x65, (char)0x6d, (char)0x73, (char)0x2e, (char)0x72, (char)0x65, (char)0x73, (char)0x40, (char)0x69, (char)0x32, (char)0x69, (char)0x32, (char)0x6e, (char)0x65, (char)0x32, (char)0x65, (char)0x74, (char)0x6d, (char)0x65, (char)0x74, (char)0x36, (char)0x6e, (char)0x72, (char)0x32, (char)0x6e, (char)0x65, (char)0x69, (char)0x32, (char)0x6f, (char)0x70, (char)0x72, (char)0x72, (char)0x65, (char)0x72, (char)0x72, (char)0x69, (char)0x6e, (char)0x6d, (char)0x69, (char)0x70, (char)0x6c, (char)0x6c, (char)0x65, (char)0x31, (char)0x72, (char)0x72, (char)0x73, (char)0x72, (char)0x70, (char)0x73, (char)0x72, (char)0x65, (char)0x65, (char)0x6e, (char)0x76, (char)0x69, (char)0x6d, (char)0x65, (char)0x6c, (char)0x65, (char)0x31, (char)0x74, (char)0x74, (char)0x72, (char)0x63, (char)0x2e, (char)0x69, (char)0x65, (char)0x2d, (char)0x6d, (char)0x72, (char)0x70, (char)0x6e, (char)0x6c, (char)0x65, (char)0x31, (char)0x73, (char)0x73, (char)0x40, (char)0x74, (char)0x72, (char)0x73, (char)0x2e, (char)0x74, (char)0x6e, (char)0x77, (char)0x6c, (char)0x6f, (char)0x70, (char)0x77, (char)0x76, (char)0x73, (char)0x72, (char)0x69, (char)0x77, (char)0x69, (char)0x6e, (char)0x69, (char)0x2d, (char)0x72, (char)0x70, (char)0x70, (char)0x73, (char)0x2e, (char)0x76, (char)0x73, (char)0x65, (char)0x72, (char)0x72, (char)0x74, (char)0x2d, (char)0x72, (char)0x65, (char)0x76, (char)0x69, (char)0x77, (char)0x72, (char)0x65, (char)0x2d, (char)0x72, (char)0x69, (char)0x36, (char)0x77, (char)0x77, (char)0x77, (char)0x40, (char)0x2d, (char)0x6d, (char)0x69, (char)0x74, (char)0x72, (char)0x2d, (char)0x32, (char)0x6f, (char)0x76, (char)0x72, (char)0x2d, (char)0x2d, (char)0x65, (char)0x2e, (char)0x2e, (char)0x72, (char)0x6e, (char)0x32, (char)0x74, (char)0x6c, (char)0x6e, (char)0x6c, (char)0x2e, (char)0x6d, (char)0x2d, (char)0x6f, (char)0x65, (char)0x72, (char)0x2d, (char)0x6e, (char)0x65, (char)0x65, (char)0x69, (char)0x40, (char)0x69, (char)0x77, (char)0x65, (char)0x6c, (char)0x2d, (char)0x69, (char)0x69, (char)0x65, (char)0x72, (char)0x72, (char)0x32, (char)0x40, (char)0x73, (char)0x65, (char)0x36, (char)0x76, (char)0x73, (char)0x72, (char)0x69, (char)0x63, (char)0x77, (char)0x72, (char)0x6c, (char)0x72, (char)0x6e, (char)0x74, (char)0x2d, (char)0x65, (char)0x69, (char)0x72, (char)0x70, (char)0x6d, (char)0x65, (char)0x6c, (char)0x73, (char)0x65, (char)0x6c, (char)0x32, (char)0x2d, (char)0x73, (char)0x70, (char)0x2d, (char)0x31, (char)0x72, (char)0x74, (char)0x2e, (char)0x65, (char)0x74, (char)0x72, (char)0x74, (char)0x72, (char)0x70, (char)0x69, (char)0x40, (char)0x36, (char)0x2d, (char)0x74, (char)0x72, (char)0x6c, (char)0x2d, (char)0x6e, (char)0x72, (char)0x6e, (char)0x6d, (char)0x63, (char)0x76, (char)0x74, (char)0x6d, (char)0x70, (char)0x32, (char)0x70, (char)0x69, (char)0x69, (char)0x2d, (char)0x73, (char)0x72, (char)0x74, (char)0x65, (char)0x74, (char)0x74, (char)0x70, (char)0x2d, (char)0x31, (char)0x6c, (char)0x77, (char)0x65, (char)0x72, (char)0x70, (char)0x73, (char)0x36, (char)0x6c, (char)0x72, (char)0x72, (char)0x65, (char)0x65, (char)0x76, (char)0x69, (char)0x2e, (char)0x6e, (char)0x72, (char)0x72, (char)0x36, (char)0x65, (char)0x69, (char)0x72, (char)0x69, (char)0x40, (char)0x6c, (char)0x74, (char)0x6c, (char)0x72, (char)0x2d, (char)0x70, (char)0x74, (char)0x76, (char)0x74, (char)0x6f, (char)0x72, (char)0x31, (char)0x73, (char)0x70, (char)0x65, (char)0x74, (char)0x69, (char)0x6e, (char)0x69, (char)0x6c, (char)0x70, (char)0x72, (char)0x65, (char)0x70, (char)0x72, (char)0x73, (char)0x69, (char)0x2d, (char)0x6d, (char)0x63, (char)0x2d, (char)0x72, (char)0x2d, (char)0x36, (char)0x73, (char)0x6e, (char)0x2d, (char)0x6d, (char)0x69, (char)0x76, (char)0x76, (char)0x6d, (char)0x74, (char)0x72, (char)0x77, (char)0x74, (char)0x2e, (char)0x6d, (char)0x65, (char)0x2d, (char)0x65, (char)0x6d, (char)0x2e, (char)0x6c, (char)0x73, (char)0x6e, (char)0x6f, (char)0x76, (char)0x31, (char)0x74, (char)0x65, (char)0x65, (char)0x31, (char)0x69, (char)0x65, (char)0x32, (char)0x2d, (char)0x74, (char)0x2d, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x70, (char)0x65, (char)0x6e, (char)0x2d, (char)0x69, (char)0x32, (char)0x72, (char)0x73, (char)0x74, (char)0x65, (char)0x65, (char)0x69, (char)0x73, (char)0x77, (char)0x77, (char)0x2e, (char)0x6e, (char)0x72, (char)0x65, (char)0x70, (char)0x76, (char)0x40, (char)0x77, (char)0x65, (char)0x2d, (char)0x70, (char)0x36, (char)0x2d, (char)0x74, (char)0x65, (char)0x2d, (char)0x69, (char)0x74, (char)0x76, (char)0x69, (char)0x6e, (char)0x65, (char)0x2d, (char)0x65, (char)0x73, (char)0x31, (char)0x36, (char)0x69, (char)0x31, (char)0x74, (char)0x76, (char)0x65, (char)0x77, (char)0x6c, (char)0x6e, (char)0x6c, (char)0x32, (char)0x6e, (char)0x70, (char)0x73, (char)0x69, (char)0x69, (char)0x65, (char)0x72, (char)0x2d, (char)0x6e, (char)0x2d, (char)0x65, (char)0x65, (char)0x6c, (char)0x32, (char)0x77, (char)0x72, (char)0x69, (char)0x70, (char)0x76, (char)0x32, (char)0x65, (char)0x6c, (char)0x36, (char)0x65, (char)0x69, (char)0x31, (char)0x6e, (char)0x72, (char)0x6c, (char)0x6d, (char)0x65, (char)0x65, (char)0x77, (char)0x6e, (char)0x2d, (char)0x32, (char)0x77, (char)0x69, (char)0x65, (char)0x6d, (char)0x74, (char)0x77, (char)0x40, (char)0x65, (char)0x6e, (char)0x77, (char)0x73, (char)0x65, (char)0x72, (char)0x6c, (char)0x40, (char)0x65, (char)0x65, (char)0x72, (char)0x72, (char)0x74, (char)0x6e, (char)0x6c, (char)0x6d, (char)0x73, (char)0x69, (char)0x76, (char)0x72, (char)0x31, (char)0x2d, (char)0x65, (char)0x36, (char)0x72, (char)0x2d, (char)0x70, (char)0x69, (char)0x6e, (char)0x63, (char)0x31, (char)0x2d, (char)0x69, (char)0x6e, (char)0x65, (char)0x2d, (char)0x65, (char)0x2e, (char)0x77, (char)0x2d, (char)0x72, (char)0x76, (char)0x63, (char)0x69, (char)0x2d, (char)0x6d, (char)0x70, (char)0x2d, (char)0x6c, (char)0x69, (char)0x63, (char)0x69, (char)0x77, (char)0x6e, (char)0x69, (char)0x77, (char)0x36, (char)0x72, (char)0x69, (char)0x72, (char)0x2e, (char)0x74, (char)0x72, (char)0x6e, (char)0x65, (char)0x6f, (char)0x73, (char)0x2d, (char)0x2e, (char)0x72, (char)0x63, (char)0x76, (char)0x74, (char)0x36, (char)0x65, (char)0x72, (char)0x65, (char)0x6d, (char)0x32, (char)0x72, (char)0x70, (char)0x40, (char)0x65, (char)0x74, (char)0x6e, (char)0x32, (char)0x70, (char)0x2d, (char)0x31, (char)0x40, (char)0x6c, (char)0x65, (char)0x6c, (char)0x76, (char)0x69, (char)0x69, (char)0x76, (char)0x76, (char)0x73, (char)0x31, (char)0x6e, (char)0x65, (char)0x74, (char)0x65, (char)0x6d, (char)0x69, (char)0x2d, (char)0x72, (char)0x74, (char)0x74, (char)0x6c, (char)0x31, (char)0x74, (char)0x6e, (char)0x6e, (char)0x65, (char)0x77, (char)0x36, (char)0x69, (char)0x69, (char)0x72, (char)0x6e, (char)0x2d, (char)0x2d, (char)0x2d, (char)0x72, (char)0x73, (char)0x76, (char)0x72, (char)0x72, (char)0x65, (char)0x72, (char)0x65, (char)0x72, (char)0x2d, (char)0x6c, (char)0x76, (char)0x77, (char)0x63, (char)0x77, (char)0x72, (char)0x6d, (char)0x72, (char)0x2e, (char)0x65, (char)0x73, (char)0x32, (char)0x72, (char)0x36, (char)0x77, (char)0x72, (char)0x72, (char)0x6d, (char)0x74, (char)0x2d, (char)0x72, (char)0x2e, (char)0x73, (char)0x73, (char)0x65, (char)0x77, (char)0x6e, (char)0x65, (char)0x69, (char)0x65, (char)0x2d, (char)0x65, (char)0x77, (char)0x6f, (char)0x74, (char)0x72, (char)0x32, (char)0x40, (char)0x6e, (char)0x72, (char)0x69, (char)0x6e, (char)0x32, (char)0x70, (char)0x73, (char)0x72, (char)0x40, (char)0x2d, (char)0x65, (char)0x69, (char)0x65, (char)0x77, (char)0x65, (char)0x70, (char)0x40, (char)0x36, (char)0x72, (char)0x6c, (char)0x6d, (char)0x73, (char)0x69, (char)0x72, (char)0x72, (char)0x74, (char)0x36, (char)0x6c, (char)0x76, (char)0x65, (char)0x76, (char)0x2d, (char)0x74, (char)0x6c, (char)0x72, (char)0x72, (char)0x74, (char)0x6e, (char)0x73, (char)0x74, (char)0x69, (char)0x72, (char)0x6d, (char)0x40, (char)0x2d, (char)0x6e, (char)0x70, (char)0x73, (char)0x2d, (char)0x6d, (char)0x72, (char)0x72, (char)0x70, (char)0x65, (char)0x65, (char)0x36, (char)0x6e, (char)0x77, (char)0x2d, (char)0x69, (char)0x2d, (char)0x32, (char)0x72, (char)0x6d, (char)0x72, (char)0x6c, (char)0x32, (char)0x6c, (char)0x73, (char)0x6d, (char)0x65, (char)0x36, (char)0x69, (char)0x69, (char)0x72, (char)0x77, (char)0x74, (char)0x6f, (char)0x72, (char)0x6d, (char)0x6d, (char)0x69, (char)0x65, (char)0x73, (char)0x63, (char)0x65, (char)0x74, (char)0x74, (char)0x72, (char)0x65, (char)0x72, (char)0x2e, (char)0x6e, (char)0x73, (char)0x65, (char)0x76, (char)0x6c, (char)0x76, (char)0x77, (char)0x72, (char)0x6e, (char)0x6c, (char)0x32, (char)0x2d, (char)0x73, (char)0x65, (char)0x73, (char)0x2e, (char)0x76, (char)0x72, (char)0x65, (char)0x2d, (char)0x72, (char)0x77, (char)0x2d, (char)0x77, (char)0x70, (char)0x65, (char)0x6c, (char)0x72, (char)0x6e, (char)0x2e, (char)0x31, (char)0x73, (char)0x2e, (char)0x72, (char)0x6d, (char)0x6d, (char)0x69, (char)0x74, (char)0x74, (char)0x6d, (char)0x32, (char)0x70, (char)0x76, (char)0x76, (char)0x31, (char)0x76, (char)0x77, (char)0x65, (char)0x6e, (char)0x73, (char)0x63, (char)0x2e, (char)0x2d, (char)0x69, (char)0x6e, (char)0x69, (char)0x77, (char)0x6e, (char)0x65, (char)0x6d, (char)0x2d, (char)0x72, (char)0x6e, (char)0x74, (char)0x6e, (char)0x40, (char)0x73, (char)0x2d, (char)0x74, (char)0x74, (char)0x65, (char)0x72, (char)0x2d, (char)0x2d, (char)0x69, (char)0x73, (char)0x70,
        (char)0x69, (char)0x6c, (char)0x72, (char)0x76, (char)0x6d, (char)0x74, (char)0x6e, (char)0x73, (char)0x74, (char)0x72, (char)0x65, (char)0x63, (char)0x69, (char)0x65, (char)0x65, (char)0x72, (char)0x6f, (char)0x6e, (char)0x72, (char)0x72, (char)0x6c, (char)0x6e, (char)0x6e, (char)0x65, (char)0x6d, (char)0x74, (char)0x6c, (char)0x74, (char)0x65, (char)0x69, (char)0x2d, (char)0x6f, (char)0x69, (char)0x2e, (char)0x6e, (char)0x63, (char)0x65, (char)0x6c, (char)0x40, (char)0x70, (char)0x2d, (char)0x2d, (char)0x74, (char)0x73, (char)0x74, (char)0x40, (char)0x72, (char)0x74, (char)0x6c, (char)0x72, (char)0x6e, (char)0x6f, (char)0x73, (char)0x65, (char)0x74, (char)0x6d, (char)0x69, (char)0x32, (char)0x72, (char)0x65, (char)0x77, (char)0x6e, (char)0x76, (char)0x74, (char)0x73, (char)0x2d, (char)0x72, (char)0x6e, (char)0x69, (char)0x73, (char)0x40, (char)0x36, (char)0x2d, (char)0x6d, (char)0x2e, (char)0x65, (char)0x6d, (char)0x40, (char)0x69, (char)0x72, (char)0x72, (char)0x70, (char)0x65, (char)0x72, (char)0x76, (char)0x6c, (char)0x65, (char)0x76, (char)0x72, (char)0x65, (char)0x69, (char)0x65, (char)0x69, (char)0x6e, (char)0x72, (char)0x2d, (char)0x63, (char)0x72, (char)0x69, (char)0x6e, (char)0x72, (char)0x69, (char)0x6e, (char)0x69, (char)0x70, (char)0x6e, (char)0x2d, (char)0x69, (char)0x6c, (char)0x72, (char)0x2d, (char)0x65, (char)0x2d, (char)0x72, (char)0x6f, (char)0x65, (char)0x6e, (char)0x76, (char)0x6e, (char)0x40, (char)0x2d, (char)0x65, (char)0x72, (char)0x72, (char)0x6f, (char)0x6f, (char)0x72, (char)0x6c, (char)0x65, (char)0x74, (char)0x73, (char)0x72, (char)0x70, (char)0x77, (char)0x69, (char)0x69, (char)0x6d, (char)0x6c, (char)0x6d, (char)0x6e, (char)0x2d, (char)0x65, (char)0x65, (char)0x65, (char)0x74, (char)0x6c, (char)0x2d, (char)0x74, (char)0x6f, (char)0x2d, (char)0x74, (char)0x70, (char)0x72, (char)0x6e, (char)0x73, (char)0x72, (char)0x69, (char)0x72, (char)0x2e, (char)0x6d, (char)0x69, (char)0x65, (char)0x65, (char)0x32, (char)0x70, (char)0x6c, (char)0x6c, (char)0x65, (char)0x77, (char)0x2d, (char)0x72, (char)0x6f, (char)0x70, (char)0x76, (char)0x65, (char)0x2d, (char)0x72, (char)0x69, (char)0x6d, (char)0x72, (char)0x36, (char)0x40, (char)0x6d, (char)0x72, (char)0x6c, (char)0x6d, (char)0x77, (char)0x6c, (char)0x6e, (char)0x69, (char)0x72, (char)0x6d, (char)0x76, (char)0x73, (char)0x2e, (char)0x73, (char)0x72, (char)0x77, (char)0x73, (char)0x76, (char)0x2d, (char)0x73, (char)0x76, (char)0x6d, (char)0x76, (char)0x65, (char)0x69, (char)0x76, (char)0x63, (char)0x65, (char)0x72, (char)0x31, (char)0x72, (char)0x69, (char)0x76, (char)0x72, (char)0x65, (char)0x65, (char)0x2d, (char)0x73, (char)0x6d, (char)0x31, (char)0x72, (char)0x6e, (char)0x72, (char)0x2d, (char)0x2d, (char)0x36, (char)0x72, (char)0x73, (char)0x77, (char)0x2d, (char)0x77, (char)0x36, (char)0x76, (char)0x72, (char)0x6d, (char)0x65, (char)0x2d, (char)0x72, (char)0x70, (char)0x2d, (char)0x74, (char)0x32, (char)0x6c, (char)0x63, (char)0x6d, (char)0x6f, (char)0x6e, (char)0x2e, (char)0x2d, (char)0x69, (char)0x65, (char)0x73, (char)0x6d, (char)0x65, (char)0x73, (char)0x6e, (char)0x6d, (char)0x6c, (char)0x65, (char)0x6e, (char)0x72, (char)0x72, (char)0x72, (char)0x32, (char)0x70, (char)0x65, (char)0x73, (char)0x6c, (char)0x6d, (char)0x70, (char)0x6d, (char)0x72, (char)0x6f, (char)0x65, (char)0x6c, (char)0x76, (char)0x73, (char)0x63, (char)0x73, (char)0x65, (char)0x6c, (char)0x2d, (char)0x6e, (char)0x72, (char)0x65, (char)0x65, (char)0x72, (char)0x2d, (char)0x70, (char)0x6d, (char)0x69, (char)0x69, (char)0x65, (char)0x2d, (char)0x6c, (char)0x72, (char)0x69, (char)0x6c, (char)0x2d, (char)0x74, (char)0x65, (char)0x65, (char)0x69, (char)0x31, (char)0x72, (char)0x69, (char)0x6d, (char)0x69, (char)0x74, (char)0x74, (char)0x73, (char)0x65, (char)0x32, (char)0x2d, (char)0x6f, (char)0x2d, (char)0x70, (char)0x72, (char)0x6f, (char)0x65, (char)0x69, (char)0x73, (char)0x32, (char)0x6d, (char)0x65, (char)0x2d, (char)0x65, (char)0x74, (char)0x6d, (char)0x6d, (char)0x73, (char)0x76, (char)0x6c, (char)0x69, (char)0x65, (char)0x2d, (char)0x73, (char)0x74, (char)0x65, (char)0x65, (char)0x72, (char)0x72, (char)0x74, (char)0x31, (char)0x2d, (char)0x76, (char)0x73, (char)0x2e, (char)0x2d, (char)0x2d, (char)0x72, (char)0x76, (char)0x77, (char)0x65, (char)0x72, (char)0x72, (char)0x40, (char)0x6e, (char)0x6c, (char)0x6d, (char)0x72, (char)0x74, (char)0x73, (char)0x72, (char)0x72, (char)0x65, (char)0x65, (char)0x2d, (char)0x6f, (char)0x74, (char)0x70, (char)0x63, (char)0xb8, (char)0xa1, (char)0x11, (char)0x6e, (char)0xd7, (char)0x74, (char)0x16, (char)0x7f, (char)0xb4, (char)0xba, (char)0x40, (char)0x93, (char)0x98, (char)0x00, (char)0x71, (char)0xcc, (char)0x42, (char)0xa7, (char)0x2f, (char)0x28, (char)0x69, (char)0xe7, (char)0x31, (char)0x48, (char)0x22, (char)0xa0, (char)0xe1, (char)0x45, (char)0xe3, (char)0xf7, (char)0x7f, (char)0x3a
    };
    char c2[] = {
        (char)0x5b, (char)0x52, (char)0xf1, (char)0x2d, (char)0x94, (char)0xcb, (char)0xb0, (char)0x86, (char)0xd8, (char)0xd3, (char)0xe3, (char)0x20, (char)0x88, (char)0x47, (char)0xcf, (char)0x5a, (char)0x49, (char)0xd2, (char)0x11, (char)0x30, (char)0x92, (char)0x17, (char)0x8d, (char)0xf4, (char)0x99, (char)0xf7, (char)0x6c, (char)0x8a, (char)0xbc, (char)0xe7, (char)0x5c, (char)0x58, (char)0x6a, (char)0x65, (char)0xed, (char)0x81, (char)0xdc, (char)0xdd, (char)0xcf, (char)0x83, (char)0xcd, (char)0xa4, (char)0xed, (char)0xa2, (char)0x5e, (char)0x63, (char)0xd9, (char)0x98, (char)0xf6, (char)0x2e, (char)0x15, (char)0x76, (char)0x9a, (char)0xc8, (char)0x8c, (char)0x42, (char)0x54, (char)0x44, (char)0xf4, (char)0x47, (char)0xf5, (char)0x96, (char)0xc9, (char)0x6e, (char)0x23, (char)0x09, (char)0x1a, (char)0x0d, (char)0xe3, (char)0x04, (char)0xe6, (char)0xed, (char)0x48, (char)0x49, (char)0x62, (char)0x31, (char)0xe8, (char)0x36, (char)0x04, (char)0xed, (char)0xb9, (char)0xe7, (char)0xa6, (char)0x35, (char)0x4d, (char)0xcd, (char)0xe3, (char)0xfa, (char)0xa0, (char)0xc8, (char)0x34, (char)0xbd, (char)0x62, (char)0x7b, (char)0xbc, (char)0xbe, (char)0x1c, (char)0x5b, (char)0x69, (char)0x1f, (char)0x9c, (char)0x30, (char)0x20, (char)0x48, (char)0x52, (char)0xd1, (char)0xb6, (char)0x5e, (char)0xa2, (char)0x6e, (char)0x06, (char)0x94, (char)0x72, (char)0x10, (char)0x56, (char)0x7c, (char)0x94, (char)0xa5, (char)0xc0, (char)0xaa, (char)0xea, (char)0x48, (char)0x61, (char)0x03, (char)0x14, (char)0x94, (char)0x09, (char)0x77, (char)0xd9, (char)0xa7, (char)0xfe, (char)0x78, (char)0x17, (char)0x95, (char)0x4f, (char)0x7e, (char)0xb0, (char)0x32, (char)0x63, (char)0x02, (char)0x17, (char)0x47, (char)0x1e, (char)0x7d, (char)0xb2, (char)0x7d, (char)0xb5, (char)0xcb, (char)0x9f, (char)0x61, (char)0x65, (char)0xed, (char)0x03, (char)0xd2, (char)0xdb, (char)0xd1, (char)0xb3, (char)0xd6, (char)0x1a, (char)0xf5, (char)0x67, (char)0x0b, (char)0x8b, (char)0x6b, (char)0x44, (char)0xf2, (char)0x62, (char)0x42, (char)0xc2, (char)0x4d, (char)0xe1, (char)0x5c, (char)0xfe, (char)0xc6, (char)0x19, (char)0x2b, (char)0xfb, (char)0x03, (char)0x0f, (char)0x1b, (char)0x89, (char)0x08, (char)0x86, (char)0x40, (char)0xca, (char)0x45, (char)0x15, (char)0xda, (char)0x65, (char)0xcc, (char)0x73, (char)0x00, (char)0x49, (char)0x4e, (char)0x48, (char)0x21, (char)0x25, (char)0xc6, (char)0xde, (char)0x26, (char)0x21, (char)0x1d, (char)0xea, (char)0x3c, (char)0x11, (char)0xac, (char)0xef, (char)0x34, (char)0x4c, (char)0x96, (char)0xcc, (char)0x5e, (char)0x26, (char)0xf3, (char)0xcd, (char)0x70, (char)0x0d, (char)0x62, (char)0xea, (char)0x09, (char)0x35, (char)0x2b, (char)0x1e, (char)0x60, (char)0xe4, (char)0x76, (char)0xd3, (char)0x65, (char)0x01, (char)0x8c, (char)0xab, (char)0xd4, (char)0x89, (char)0xad, (char)0x81, (char)0x9d, (char)0x04, (char)0x01, (char)0xd5, (char)0x55, (char)0x3c, (char)0xcb, (char)0x32, (char)0xe1, (char)0xb5, (char)0xd4, (char)0xda, (char)0xb4, (char)0xa9, (char)0x01, (char)0xb2, (char)0x10, (char)0xc7, (char)0xb1, (char)0xa9, (char)0x54, (char)0x66, (char)0x1d, (char)0xcc, (char)0xff, (char)0x54, (char)0x0b, (char)0x84, (char)0x37, (char)0xe0, (char)0x3a, (char)0xa5, (char)0x68, (char)0x80, (char)0x87, (char)0xbc, (char)0x3c, (char)0x0f, (char)0xda, (char)0x7e, (char)0x3c, (char)0x23, (char)0xfc, (char)0xd8, (char)0xc5, (char)0x52, (char)0xf7, (char)0x22, (char)0x12, (char)0x05, (char)0x9c, (char)0x68, (char)0x39, (char)0xb1, (char)0xed, (char)0x26, (char)0x24, (char)0x2b, (char)0x7e, (char)0x0b, (char)0xaf, (char)0x9e, (char)0x97, (char)0x45, (char)0x7b, (char)0xa9, (char)0xbc, (char)0x48, (char)0x0e, (char)0x66, (char)0x93, (char)0x32, (char)0x0d, (char)0x6b, (char)0xd6, (char)0xf0, (char)0x4f, (char)0x54, (char)0x18, (char)0xcd, (char)0xc9, (char)0x8c, (char)0xce, (char)0xc4, (char)0xa2, (char)0xff, (char)0x1e, (char)0x69, (char)0x17, (char)0x7e, (char)0xf4, (char)0x99, (char)0x09, (char)0x68, (char)0xa1, (char)0x9e, (char)0x1f, (char)0xbf, (char)0x90, (char)0xdc, (char)0x77, (char)0x5d, (char)0x50, (char)0x2b, (char)0x0e, (char)0xff, (char)0x96, (char)0xdc, (char)0x21, (char)0x2e, (char)0x74, (char)0x22, (char)0x28, (char)0x88, (char)0xa0, (char)0x00, (char)0x32, (char)0x15, (char)0xb0, (char)0xfd, (char)0xb1, (char)0xc9, (char)0x75, (char)0xb3, (char)0x3c, (char)0xbd, (char)0x89, (char)0xc5, (char)0xa4, (char)0x48, (char)0x17, (char)0xa9, (char)0xc9, (char)0x50, (char)0x61, (char)0x0c, (char)0x35, (char)0x31, (char)0x55, (char)0x11, (char)0xe3, (char)0x23, (char)0xe9, (char)0x3e, (char)0x78, (char)0x25, (char)0xdc, (char)0x50, (char)0xe8, (char)0x23, (char)0x5f, (char)0xb7, (char)0x3f, (char)0xc7, (char)0xae, (char)0xf0, (char)0x82, (char)0x35, (char)0x46, (char)0x34, (char)0x63, (char)0xcc, (char)0x5d, (char)0x96, (char)0xb8, (char)0x6a, (char)0x7a, (char)0x7f, (char)0x54, (char)0x27, (char)0x1a, (char)0xa4, (char)0x63, (char)0xdd, (char)0xb0, (char)0xb6, (char)0x17, (char)0x08, (char)0xa1, (char)0x2e, (char)0x95, (char)0x9e, (char)0xd4, (char)0x9b, (char)0x71, (char)0x83, (char)0x81, (char)0x6c, (char)0xea, (char)0xab, (char)0x00, (char)0x2e, (char)0xca, (char)0x60, (char)0xc1, (char)0x4b, (char)0x83, (char)0xa7, (char)0xab, (char)0x47, (char)0xe8, (char)0x1b, (char)0x5a, (char)0x78, (char)0x4f, (char)0xec, (char)0xbd, (char)0x62, (char)0x94, (char)0x25, (char)0x75, (char)0x2e, (char)0x64, (char)0xe7, (char)0x70, (char)0x13, (char)0xac, (char)0xe9, (char)0x89, (char)0x4f, (char)0x1e, (char)0x79, (char)0xbc, (char)0x15, (char)0x0c, (char)0x8d, (char)0x40, (char)0xe8, (char)0x16, (char)0x31, (char)0x7c, (char)0xb8, (char)0xa5, (char)0xd7, (char)0x21, (char)0x39, (char)0x93, (char)0x9b, (char)0xe6, (char)0x05, (char)0x81, (char)0xb6, (char)0x20, (char)0xa8, (char)0x5d, (char)0x73, (char)0x58, (char)0x8b, (char)0x66, (char)0x92, (char)0xac, (char)0x23, (char)0xa0, (char)0xf4, (char)0x8c, (char)0xab, (char)0x58, (char)0xae, (char)0xb6, (char)0x9c, (char)0x3c, (char)0x4d, (char)0x77, (char)0x5f, (char)0xae, (char)0xe2, (char)0x57, (char)0x89, (char)0x8f, (char)0xe4, (char)0x68, (char)0x81, (char)0x24, (char)0x7d, (char)0x3b, (char)0x99, (char)0x46, (char)0x9f, (char)0x7b, (char)0x9d, (char)0xa6, (char)0xdd, (char)0x99, (char)0xcf, (char)0xc1, (char)0x79, (char)0x04, (char)0x95, (char)0xce, (char)0x96, (char)0x7a, (char)0xd9, (char)0xb5, (char)0x6e, (char)0xcf, (char)0xd1, (char)0x72, (char)0x18, (char)0x97, (char)0x76, (char)0xe2, (char)0xb7, (char)0x38, (char)0x1e, (char)0x24, (char)0x0b, (char)0x09, (char)0x00, (char)0x8b, (char)0x28, (char)0x5d, (char)0xf8, (char)0xd0, (char)0x50, (char)0x7f, (char)0xeb, (char)0x3b, (char)0x37, (char)0x61, (char)0x0b, (char)0xd3, (char)0xff, (char)0x65, (char)0x7d, (char)0x88, (char)0x1e, (char)0x1d, (char)0xbb, (char)0x6c, (char)0xf5, (char)0xf8, (char)0xf3, (char)0x2b, (char)0x51, (char)0xd9, (char)0x6d, (char)0xc9, (char)0xbe, (char)0xbe, (char)0xd1, (char)0x94, (char)0x0e, (char)0x58, (char)0x2a, (char)0x0a, (char)0xe4, (char)0xf8, (char)0x28, (char)0x26, (char)0xc3, (char)0x74, (char)0x87, (char)0xd3, (char)0x81, (char)0x48, (char)0x6e, (char)0x9b, (char)0xd5, (char)0xa1, (char)0x60, (char)0x87, (char)0xfc, (char)0x1b, (char)0x06, (char)0x33, (char)0x0d, (char)0x87, (char)0xfa, (char)0x9b, (char)0xf9, (char)0x73, (char)0x6b, (char)0x0c, (char)0xdf, (char)0xea, (char)0xee, (char)0x32, (char)0x78, (char)0xe0, (char)0xf8, (char)0x18, (char)0x3f, (char)0xc3, (char)0x3b, (char)0x12, (char)0x88, (char)0x0b, (char)0xb2, (char)0x4a, (char)0x52, (char)0x64, (char)0x4e, (char)0x58, (char)0x54, (char)0x82, (char)0x52, (char)0x61, (char)0x54, (char)0x28, (char)0x1b, (char)0xf7, (char)0x99, (char)0x06, (char)0xa2, (char)0xad, (char)0x04, (char)0x19, (char)0x9f, (char)0x2e, (char)0x34, (char)0xe6, (char)0xf0, (char)0xee, (char)0xeb, (char)0x93, (char)0x9a, (char)0x9c, (char)0x73, (char)0x86, (char)0x23, (char)0x6d, (char)0x5d, (char)0xae, (char)0x64, (char)0xec, (char)0x6f, (char)0xf9, (char)0x7c, (char)0xc7, (char)0x46, (char)0x96, (char)0xdb, (char)0x44, (char)0xf4, (char)0xab, (char)0xc9, (char)0x67, (char)0x61, (char)0xb8, (char)0xec, (char)0xf0, (char)0x99, (char)0xe0, (char)0x4d, (char)0x45, (char)0xed, (char)0xa3, (char)0x1c, (char)0xe9, (char)0x68, (char)0x31, (char)0x85, (char)0xa5, (char)0xa1, (char)0xba, (char)0x08, (char)0xdb, (char)0x3f, (char)0x84, (char)0x75, (char)0x70, (char)0x24, (char)0xcd, (char)0x49, (char)0xd4, (char)0x07, (char)0xa8, (char)0xaa, (char)0x52, (char)0xd9, (char)0x55, (char)0x68, (char)0x8f, (char)0x78, (char)0xd2, (char)0x5d, (char)0x46, (char)0x23, (char)0x60, (char)0x76, (char)0xe1, (char)0x22, (char)0xdc, (char)0x2a, (char)0xeb, (char)0xac, (char)0xbc, (char)0xeb, (char)0xd6, (char)0x4c, (char)0x0f, (char)0xb5, (char)0xcb, (char)0x47, (char)0xce, (char)0x43, (char)0x59, (char)0x1d, (char)0x3e, (char)0xfc, (char)0x7f, (char)0x7c, (char)0x93, (char)0x9e, (char)0xef, (char)0xcd, (char)0x79, (char)0x5c, (char)0x08, (char)0x8e, (char)0xeb, (char)0xa8, (char)0x98, (char)0x3e, (char)0x95, (char)0xd1, (char)0x36, (char)0x42, (char)0x57, (char)0xfd, (char)0x6d, (char)0xdc, (char)0xe0, (char)0xa3, (char)0x3f, (char)0x46, (char)0x32, (char)0xb7, (char)0xff, (char)0x00, (char)0x4f, (char)0x7b, (char)0x23, (char)0x4d, (char)0xd0, (char)0xe5, (char)0xdd, (char)0x40, (char)0xab, (char)0xb2, (char)0xcb, (char)0x45, (char)0x92, (char)0x76, (char)0x7c, (char)0x5b, (char)0x98, (char)0xc7, (char)0xc0, (char)0x54, (char)0x34, (char)0x94, (char)0x8e, (char)0xbb, (char)0x28, (char)0xcf, (char)0xba, (char)0xd9, (char)0xa0, (char)0xe6, (char)0xf3, (char)0x65, (char)0x61, (char)0xd7, (char)0x10, (char)0xd3, (char)0xeb, (char)0xce, (char)0x21, (char)0x6a, (char)0xca, (char)0x61, (char)0xe7, (char)0x81, (char)0x15, (char)0x18, (char)0x4e, (char)0x71, (char)0xb0, (char)0x99, (char)0x62, (char)0xd9, (char)0xeb, (char)0xd0, (char)0x8b, (char)0xe9, (char)0xdf, (char)0x6a, (char)0x6d, (char)0x59, (char)0x0b, (char)0x45, (char)0x93, (char)0x38, (char)0xfe, (char)0xe6, (char)0x6a, (char)0xd1, (char)0x5f, (char)0xb6, (char)0xe9, (char)0x86, (char)0x01, (char)0x38, (char)0xab, (char)0x59, (char)0x5c, (char)0xd7, (char)0xb7, (char)0xfa, (char)0x81, (char)0x8a, (char)0xbe, (char)0xdc, (char)0xeb, (char)0x50, (char)0x7d, (char)0x81, (char)0xfa, (char)0x1b, (char)0x8f, (char)0xce, (char)0x53, (char)0x38, (char)0xe4, (char)0x8a, (char)0x82, (char)0xbe, (char)0x7d, (char)0xdc, (char)0xd8, (char)0x57, (char)0x5a, (char)0x48, (char)0xa3, (char)0x38, (char)0x74, (char)0x8a, (char)0xac, (char)0xf2, (char)0xfd, (char)0xbf, (char)0xcc, (char)0xd8, (char)0x08, (char)0x4d, (char)0x3e, (char)0xae, (char)0xa9, (char)0x00, (char)0x66, (char)0x06, (char)0xcb, (char)0xf3,
        (char)0x50, (char)0xcc, (char)0x52, (char)0xc7, (char)0x4b, (char)0x16, (char)0x33, (char)0xa5, (char)0xde, (char)0x20, (char)0xed, (char)0x6a, (char)0xa7, (char)0x58, (char)0x5e, (char)0x4e, (char)0x7e, (char)0x29, (char)0xab, (char)0xb9, (char)0x65, (char)0x9d, (char)0x17, (char)0xe0, (char)0x1e, (char)0x79, (char)0x77, (char)0xf6, (char)0x1e, (char)0xa0, (char)0xcb, (char)0x0c, (char)0xf7, (char)0xc0, (char)0xe4, (char)0xf6, (char)0x3b, (char)0x60, (char)0x81, (char)0xfe, (char)0xed, (char)0xd9, (char)0x42, (char)0xa9, (char)0x61, (char)0x9d, (char)0xa8, (char)0xd7, (char)0xe8, (char)0xaa, (char)0x97, (char)0xad, (char)0xbb, (char)0xba, (char)0x13, (char)0x6e, (char)0x05, (char)0xa5, (char)0xce, (char)0x7a, (char)0x65, (char)0x6f, (char)0x55, (char)0xe3, (char)0xcf, (char)0xbc, (char)0x67, (char)0x14, (char)0x64, (char)0x57, (char)0x9c, (char)0x46, (char)0x14, (char)0xd6, (char)0x1d, (char)0x39, (char)0x1c, (char)0xd3, (char)0xe8, (char)0x98, (char)0x20, (char)0x5a, (char)0x1a, (char)0x05, (char)0x3b, (char)0x27, (char)0xd5, (char)0x84, (char)0xca, (char)0xd4, (char)0x0b, (char)0xc4, (char)0x1e, (char)0xd8, (char)0x46, (char)0x29, (char)0x48, (char)0x95, (char)0xdb, (char)0xe5, (char)0x58, (char)0x8a, (char)0x51, (char)0xc7, (char)0x74, (char)0x7f, (char)0x53, (char)0xa8, (char)0xbb, (char)0x58, (char)0xc0, (char)0x5b, (char)0xe1, (char)0xa7, (char)0x27, (char)0x36, (char)0x6c, (char)0xa6, (char)0x70, (char)0xec, (char)0x88, (char)0xcd, (char)0x9a, (char)0x70, (char)0xe1, (char)0xa0, (char)0xc7, (char)0xdd, (char)0x60, (char)0x71, (char)0xf4, (char)0x2a, (char)0x51, (char)0x98, (char)0x8e, (char)0xab, (char)0xb8, (char)0x13, (char)0x03, (char)0x48, (char)0x5f, (char)0x44, (char)0xf8, (char)0x88, (char)0xd9, (char)0x7d, (char)0xd3, (char)0xf1, (char)0x5f, (char)0xc4, (char)0x2b, (char)0x44, (char)0x15, (char)0x57, (char)0x31, (char)0xa4, (char)0xa1, (char)0xdb, (char)0x6d, (char)0x2a, (char)0x5a, (char)0x5a, (char)0xf7, (char)0xde, (char)0xd5, (char)0x23, (char)0x38, (char)0x00, (char)0xe5, (char)0x5c, (char)0x55, (char)0xe7, (char)0x37, (char)0x9c, (char)0xcb, (char)0x8b, (char)0xc0, (char)0x33, (char)0x42, (char)0x68, (char)0x23, (char)0x84, (char)0x7d, (char)0x89, (char)0x9d, (char)0xae, (char)0x59, (char)0x18, (char)0xae, (char)0xea, (char)0x46, (char)0x3f, (char)0xac, (char)0x57, (char)0x0d, (char)0x5d, (char)0x49, (char)0x14, (char)0x50, (char)0xe5, (char)0x70, (char)0x17, (char)0x73, (char)0x09, (char)0x11, (char)0x93, (char)0x6b, (char)0x02, (char)0x22, (char)0xb7, (char)0x63, (char)0xc9, (char)0xe6, (char)0xa4, (char)0xe3, (char)0xb1, (char)0xf7, (char)0xa6, (char)0x58, (char)0x8d, (char)0x14, (char)0xa1, (char)0xda, (char)0x6a, (char)0xb9, (char)0x38, (char)0xf9, (char)0x20, (char)0x45, (char)0x8c, (char)0xe6, (char)0x32, (char)0x23, (char)0x9d, (char)0x5f, (char)0xba, (char)0xcb, (char)0xb4, (char)0x95, (char)0xf9, (char)0xa9, (char)0x5c, (char)0x60, (char)0x03, (char)0x5a, (char)0x8c, (char)0xa7, (char)0xb9, (char)0x65, (char)0xa8, (char)0x84, (char)0x38, (char)0xc0, (char)0x25, (char)0xe6, (char)0xa7, (char)0xc0, (char)0x3b, (char)0xbc, (char)0x11, (char)0xed, (char)0x0e, (char)0x9a, (char)0x6f, (char)0xfe, (char)0x61, (char)0x79, (char)0x86, (char)0x92, (char)0x3a, (char)0xce, (char)0xe0, (char)0xb7, (char)0x70, (char)0xad, (char)0xe0, (char)0xcc, (char)0x88, (char)0x47, (char)0xd9, (char)0x2a, (char)0x3d, (char)0x41, (char)0x06, (char)0x77, (char)0x41, (char)0xbe, (char)0x3f, (char)0x55, (char)0x31, (char)0x54, (char)0x10, (char)0x14, (char)0x5b, (char)0xdf, (char)0x88, (char)0xb2, (char)0x9f, (char)0xff, (char)0x11, (char)0xb8, (char)0x11, (char)0xdc, (char)0x5e, (char)0x64, (char)0xf9, (char)0x97, (char)0x8a, (char)0x26, (char)0x6a, (char)0x44, (char)0xb4, (char)0x83, (char)0x83, (char)0x9b, (char)0x81, (char)0xaa, (char)0xfd, (char)0xb5, (char)0x8b, (char)0x16, (char)0x18, (char)0x2e, (char)0x5c, (char)0xe4, (char)0x5b, (char)0x8f, (char)0xdd, (char)0x7c, (char)0x1f, (char)0x33, (char)0x2f, (char)0xef, (char)0x57, (char)0x8c, (char)0x6a, (char)0x3f, (char)0x3c, (char)0x19, (char)0x5e, (char)0x73, (char)0x64, (char)0xc5, (char)0xaf, (char)0x1d, (char)0xa1, (char)0xb4, (char)0x11, (char)0xee, (char)0x6b, (char)0x7e, (char)0x66, (char)0xfb, (char)0xaa, (char)0x03, (char)0x17, (char)0xe4, (char)0xc9, (char)0x90, (char)0x4b, (char)0xf2, (char)0x50, (char)0x55, (char)0x71, (char)0xad, (char)0x31, (char)0x71, (char)0x49, (char)0xd7, (char)0x80, (char)0xd1, (char)0xa5, (char)0x9f, (char)0x6d, (char)0x71, (char)0x28, (char)0x2b, (char)0x65, (char)0xcf, (char)0x8d, (char)0xb1, (char)0x2a, (char)0x33, (char)0xdc, (char)0x93, (char)0xff, (char)0x86, (char)0xd7, (char)0xa6, (char)0xd0, (char)0x46, (char)0x66, (char)0x32, (char)0x3d, (char)0x18, (char)0x8c, (char)0xd3, (char)0xda, (char)0xf6, (char)0x1b, (char)0xa0, (char)0x2d, (char)0x29, (char)0xfd, (char)0x8d, (char)0x57, (char)0x2c, (char)0x82, (char)0xed, (char)0x38, (char)0x4a, (char)0x6f, (char)0xc4, (char)0x3c, (char)0x9a, (char)0x61, (char)0xcb, (char)0xe5, (char)0xcf, (char)0xd3, (char)0x83, (char)0xa1, (char)0x91, (char)0x93, (char)0x0d, (char)0x75, (char)0xfd, (char)0x4e, (char)0x2c, (char)0x83, (char)0xa0, (char)0x85, (char)0x27, (char)0x13, (char)0x5a, (char)0x24, (char)0xbd, (char)0x08, (char)0x1e, (char)0xe9, (char)0xab, (char)0x92, (char)0x41, (char)0xc2, (char)0x3a, (char)0xa0, (char)0xe1, (char)0xfd, (char)0x00, (char)0xb9, (char)0xf8, (char)0xca, (char)0x0b, (char)0x1a, (char)0x8e, (char)0xf6, (char)0x27, (char)0x9f, (char)0x5a, (char)0xf0, (char)0x23, (char)0x07, (char)0xc8, (char)0xbf, (char)0xf6, (char)0x74, (char)0xe7, (char)0xf8, (char)0x67, (char)0xfc, (char)0x28, (char)0x4e, (char)0x6a, (char)0x6c, (char)0xc6, (char)0x83, (char)0xe3, (char)0xf0, (char)0x01, (char)0xe0, (char)0x0f, (char)0x2d, (char)0xdf, (char)0x9e, (char)0x4b, (char)0x8b, (char)0x06, (char)0x15, (char)0x4c, (char)0x9f, (char)0xdf, (char)0x55, (char)0x14, (char)0x44, (char)0xde, (char)0x34, (char)0x35, (char)0x5a, (char)0xcb, (char)0xe5, (char)0xa7, (char)0xb5, (char)0x7e, (char)0x00, (char)0x31, (char)0x98, (char)0x5f, (char)0x51, (char)0x11, (char)0x37, (char)0xe1, (char)0xd2, (char)0x99, (char)0x8f, (char)0x70, (char)0x13, (char)0x40, (char)0xa0, (char)0xbe, (char)0xf8, (char)0xde, (char)0xac, (char)0x37, (char)0x06, (char)0xb6, (char)0x26, (char)0xf3, (char)0xb1, (char)0x97, (char)0x0b, (char)0x85, (char)0x68, (char)0x09, (char)0xa4, (char)0xc8, (char)0x34, (char)0x0a, (char)0x41, (char)0x6e, (char)0xac, (char)0x1a, (char)0x5b, (char)0xe0, (char)0x91, (char)0x6f, (char)0xa3, (char)0x0a, (char)0xf6, (char)0x05, (char)0x37, (char)0x32, (char)0xe1, (char)0x8e, (char)0xd8, (char)0xed, (char)0x55, (char)0xa3, (char)0x54, (char)0x3f, (char)0x62, (char)0x95, (char)0x82, (char)0xcf, (char)0x0a, (char)0x19, (char)0xb4, (char)0x9f, (char)0x04, (char)0xcc, (char)0x86, (char)0x7e, (char)0xf1, (char)0xe5, (char)0x8b, (char)0x67, (char)0x73, (char)0xa2, (char)0x46, (char)0x4e, (char)0xf2, (char)0x98, (char)0x94, (char)0xb5, (char)0xeb, (char)0xa5, (char)0xbd, (char)0xcb, (char)0x66, (char)0x82, (char)0xe9, (char)0x87, (char)0xe9, (char)0xe3, (char)0x50, (char)0x55, (char)0x4b, (char)0xd6, (char)0x67, (char)0x30, (char)0xe1, (char)0x7c, (char)0x15, (char)0x77, (char)0x29, (char)0xfd, (char)0x85, (char)0x67, (char)0x5a, (char)0xc4, (char)0xd5, (char)0x69, (char)0xfa, (char)0xc7, (char)0x66, (char)0x66, (char)0x49, (char)0xf7, (char)0x5a, (char)0xcd, (char)0xd1, (char)0x81, (char)0x5c, (char)0x74, (char)0x8d, (char)0xbf, (char)0xc5, (char)0xc2, (char)0xff, (char)0x4d, (char)0x90, (char)0xe8, (char)0x8e, (char)0x05, (char)0x00, (char)0xff, (char)0x7a, (char)0xd7, (char)0xb2, (char)0x7a, (char)0xad, (char)0x8b, (char)0xd6, (char)0x4b, (char)0x52, (char)0x09, (char)0x50, (char)0x4b
    };

    SrsHandshakeBytes bytes;
    ASSERT_EQ(ERROR_SUCCESS, bytes.create_c0c1());
    memcpy(bytes.c0c1, c0c1, 1537);
    ASSERT_EQ(ERROR_SUCCESS, bytes.create_s0s1s2());
    memcpy(bytes.s0s1s2, s0s1s2, 3073);
    ASSERT_EQ(ERROR_SUCCESS, bytes.create_c2());
    memcpy(bytes.c2, c2, 1536);

    MockEmptyIO eio;

    SrsSimpleHandshake hs;
    EXPECT_EQ(ERROR_SUCCESS, hs.handshake_with_client(&bytes, &eio));
    EXPECT_EQ(ERROR_SUCCESS, hs.handshake_with_server(&bytes, &eio));
}

/**
* bytes equal utility
*/
TEST(ProtocolHandshakeTest, BytesEqual) {
    char a1[] = { (char)0x01 };
    char b1[] = { (char)0x02 };
    char a2[] = { (char)0x01, (char)0x02 };
    char b2[] = { (char)0x02, (char)0x03 };

    EXPECT_TRUE(srs_bytes_equals(NULL, NULL, 0));
    EXPECT_FALSE(srs_bytes_equals(a1, NULL, 1));
    EXPECT_FALSE(srs_bytes_equals(NULL, a1, 1));
    EXPECT_FALSE(srs_bytes_equals(a1, b1, 1));
    EXPECT_TRUE(srs_bytes_equals(a1, a1, 1));
    EXPECT_TRUE(srs_bytes_equals(a1, a2, 1));
    EXPECT_FALSE(srs_bytes_equals(a1, b2, 1));
}

/**
* resolve vhost from tcUrl.
*/
TEST(ProtocolUtilityTest, VhostResolve) {
    std::string vhost = "vhost";
    std::string app = "app";
    std::string param;
    srs_vhost_resolve(vhost, app, param);
    EXPECT_STREQ("vhost", vhost.c_str());
    EXPECT_STREQ("app", app.c_str());

    app = "app?vhost=changed";
    srs_vhost_resolve(vhost, app, param);
    EXPECT_STREQ("changed", vhost.c_str());
    EXPECT_STREQ("app", app.c_str());

    app = "app?vhost=changed1&&query=true";
    srs_vhost_resolve(vhost, app, param);
    EXPECT_STREQ("changed1", vhost.c_str());
    EXPECT_STREQ("app", app.c_str());

    app = "app?other=true&&vhost=changed2&&query=true";
    srs_vhost_resolve(vhost, app, param);
    EXPECT_STREQ("changed2", vhost.c_str());
    EXPECT_STREQ("app", app.c_str());

    app = "app...other...true...vhost...changed3...query...true";
    srs_vhost_resolve(vhost, app, param);
    EXPECT_STREQ("changed3", vhost.c_str());
    EXPECT_STREQ("app", app.c_str());
}

/**
* discovery tcUrl to schema/vhost/host/port/app
*/
TEST(ProtocolUtilityTest, DiscoveryTcUrl) {
    std::string tcUrl, schema, ip, vhost, app, stream, port, param;

    // general url
    tcUrl = "rtmp://winlin.cn/live"; stream = "show";
    srs_discovery_tc_url(tcUrl, schema, ip, vhost, app, stream, port, param);
    EXPECT_STREQ("rtmp", schema.c_str());
    EXPECT_STREQ("winlin.cn", ip.c_str());
    EXPECT_STREQ("winlin.cn", vhost.c_str());
    EXPECT_STREQ("live", app.c_str());
    EXPECT_STREQ("show", stream.c_str());
    EXPECT_STREQ("1935", port.c_str());

    tcUrl = "rtmp://winlin.cn:19351/live"; stream = "show";
    srs_discovery_tc_url(tcUrl, schema, ip, vhost, app, stream, port, param);
    EXPECT_STREQ("rtmp", schema.c_str());
    EXPECT_STREQ("winlin.cn", ip.c_str());
    EXPECT_STREQ("winlin.cn", vhost.c_str());
    EXPECT_STREQ("live", app.c_str());
    EXPECT_STREQ("show", stream.c_str());
    EXPECT_STREQ("19351", port.c_str());

    tcUrl = "rtmp://winlin.cn/live"; stream = "show?key=abc";
    srs_discovery_tc_url(tcUrl, schema, ip, vhost, app, stream, port, param);
    EXPECT_STREQ("rtmp", schema.c_str());
    EXPECT_STREQ("winlin.cn", ip.c_str());
    EXPECT_STREQ("winlin.cn", vhost.c_str());
    EXPECT_STREQ("live", app.c_str());
    EXPECT_STREQ("show", stream.c_str());
    EXPECT_STREQ("1935", port.c_str());
    EXPECT_STREQ("?key=abc", param.c_str());

    tcUrl = "rtmp://winlin.cn/live"; stream = "show?key=abc&&vhost=demo.com";
    srs_discovery_tc_url(tcUrl, schema, ip, vhost, app, stream, port, param);
    EXPECT_STREQ("rtmp", schema.c_str());
    EXPECT_STREQ("winlin.cn", ip.c_str());
    EXPECT_STREQ("demo.com", vhost.c_str());
    EXPECT_STREQ("live", app.c_str());
    EXPECT_STREQ("show", stream.c_str());
    EXPECT_STREQ("1935", port.c_str());
    EXPECT_STREQ("?key=abc&&vhost=demo.com", param.c_str());

    // vhost in app
    tcUrl = "rtmp://winlin.cn/live?key=abc"; stream = "show";
    srs_discovery_tc_url(tcUrl, schema, ip, vhost, app, stream, port, param);
    EXPECT_STREQ("rtmp", schema.c_str());
    EXPECT_STREQ("winlin.cn", ip.c_str());
    EXPECT_STREQ("winlin.cn", vhost.c_str());
    EXPECT_STREQ("live", app.c_str());
    EXPECT_STREQ("show", stream.c_str());
    EXPECT_STREQ("1935", port.c_str());
    EXPECT_STREQ("?key=abc", param.c_str());

    tcUrl = "rtmp://winlin.cn/live?key=abc&&vhost=demo.com"; stream = "show";
    srs_discovery_tc_url(tcUrl, schema, ip, vhost, app, stream, port, param);
    EXPECT_STREQ("rtmp", schema.c_str());
    EXPECT_STREQ("winlin.cn", ip.c_str());
    EXPECT_STREQ("demo.com", vhost.c_str());
    EXPECT_STREQ("live", app.c_str());
    EXPECT_STREQ("show", stream.c_str());
    EXPECT_STREQ("1935", port.c_str());
    EXPECT_STREQ("?key=abc&&vhost=demo.com", param.c_str());

    // without stream
    tcUrl = "rtmp://winlin.cn/live"; stream = "";
    srs_discovery_tc_url(tcUrl, schema, ip, vhost, app, stream, port, param);
    EXPECT_STREQ("rtmp", schema.c_str());
    EXPECT_STREQ("winlin.cn", ip.c_str());
    EXPECT_STREQ("winlin.cn", vhost.c_str());
    EXPECT_STREQ("live", app.c_str());
    EXPECT_STREQ("", stream.c_str());
    EXPECT_STREQ("1935", port.c_str());

    tcUrl = "rtmp://127.0.0.1:1935/live"; stream = "";
    srs_discovery_tc_url(tcUrl, schema, ip, vhost, app, stream, port, param);
    EXPECT_STREQ("rtmp", schema.c_str());
    EXPECT_STREQ("127.0.0.1", ip.c_str());
    EXPECT_STREQ("127.0.0.1", vhost.c_str());
    EXPECT_STREQ("live", app.c_str());
    EXPECT_STREQ("", stream.c_str());
    EXPECT_STREQ("1935", port.c_str());

    tcUrl = "rtmp://127.0.0.1:19351/live"; stream = "";
    srs_discovery_tc_url(tcUrl, schema, ip, vhost, app, stream, port, param);
    EXPECT_STREQ("rtmp", schema.c_str());
    EXPECT_STREQ("127.0.0.1", ip.c_str());
    EXPECT_STREQ("127.0.0.1", vhost.c_str());
    EXPECT_STREQ("live", app.c_str());
    EXPECT_STREQ("", stream.c_str());
    EXPECT_STREQ("19351", port.c_str());

    tcUrl = "rtmp://127.0.0.1:19351/live?vhost=demo"; stream = "";
    srs_discovery_tc_url(tcUrl, schema, ip, vhost, app, stream, port, param);
    EXPECT_STREQ("rtmp", schema.c_str());
    EXPECT_STREQ("127.0.0.1", ip.c_str());
    EXPECT_STREQ("demo", vhost.c_str());
    EXPECT_STREQ("live", app.c_str());
    EXPECT_STREQ("", stream.c_str());
    EXPECT_STREQ("19351", port.c_str());

    // no vhost
    tcUrl = "rtmp://127.0.0.1:19351/live"; stream = "show";
    srs_discovery_tc_url(tcUrl, schema, ip, vhost, app, stream, port, param);
    EXPECT_STREQ("rtmp", schema.c_str());
    EXPECT_STREQ("127.0.0.1", ip.c_str());
    EXPECT_STREQ("127.0.0.1", vhost.c_str());
    EXPECT_STREQ("live", app.c_str());
    EXPECT_STREQ("show", stream.c_str());
    EXPECT_STREQ("19351", port.c_str());

    // ip and vhost
    tcUrl = "rtmp://127.0.0.1:19351/live"; stream = "show?vhost=demo";
    srs_discovery_tc_url(tcUrl, schema, ip, vhost, app, stream, port, param);
    EXPECT_STREQ("rtmp", schema.c_str());
    EXPECT_STREQ("127.0.0.1", ip.c_str());
    EXPECT_STREQ("demo", vhost.c_str());
    EXPECT_STREQ("live", app.c_str());
    EXPECT_STREQ("show", stream.c_str());
    EXPECT_STREQ("19351", port.c_str());

    // _definst_ at the end of app
    tcUrl = "rtmp://winlin.cn/live/_definst_"; stream = "show";
    srs_discovery_tc_url(tcUrl, schema, ip, vhost, app, stream, port, param);
    EXPECT_STREQ("rtmp", schema.c_str());
    EXPECT_STREQ("winlin.cn", ip.c_str());
    EXPECT_STREQ("winlin.cn", vhost.c_str());
    EXPECT_STREQ("live", app.c_str());
    EXPECT_STREQ("show", stream.c_str());
    EXPECT_STREQ("1935", port.c_str());
}

/**
* generate tcUrl from ip/vhost/app/port
*/
TEST(ProtocolUtilityTest, GenerateTcUrl) {
    string ip; string vhost; string app; string port; string tcUrl; string param;

    ip = "127.0.0.1"; vhost = "__defaultVhost__"; app = "live"; port = "1935";
    tcUrl = srs_generate_tc_url(ip, vhost, app, port, param);
    EXPECT_STREQ("rtmp://127.0.0.1/live", tcUrl.c_str());

    ip = "127.0.0.1"; vhost = "demo"; app = "live"; port = "1935";
    tcUrl = srs_generate_tc_url(ip, vhost, app, port, param);
    EXPECT_STREQ("rtmp://demo/live", tcUrl.c_str());

    ip = "127.0.0.1"; vhost = "demo"; app = "live"; port = "19351";
    tcUrl = srs_generate_tc_url(ip, vhost, app, port, param);
    EXPECT_STREQ("rtmp://demo:19351/live", tcUrl.c_str());
}

/**
* shared ptr message array test
*/
TEST(ProtocolMsgArrayTest, MessageArray) {
    SrsMessageHeader header;
    SrsSharedPtrMessage msg;
    char* payload = new char[1024];
    EXPECT_TRUE(ERROR_SUCCESS == msg.create(&header, payload, 1024));
    EXPECT_EQ(0, msg.count());

    if (true) {
        SrsMessageArray arr(3);

        arr.msgs[0] = msg.copy();
        EXPECT_EQ(1, msg.count());

        arr.msgs[1] = msg.copy();
        EXPECT_EQ(2, msg.count());

        arr.msgs[2] = msg.copy();
        EXPECT_EQ(3, msg.count());
    }
    EXPECT_EQ(3, msg.count());

    if (true) {
        SrsMessageArray arr(3);

        arr.msgs[0] = msg.copy();
        EXPECT_EQ(4, msg.count());

        arr.msgs[2] = msg.copy();
        EXPECT_EQ(5, msg.count());
    }
    EXPECT_EQ(5, msg.count());
}

/**
* set/get timeout of protocol stack
*/
TEST(ProtocolStackTest, ProtocolTimeout) {
    MockBufferIO bio;
    SrsProtocol proto(&bio);

    EXPECT_TRUE((int64_t)ST_UTIME_NO_TIMEOUT == proto.get_recv_timeout());
    EXPECT_TRUE((int64_t)ST_UTIME_NO_TIMEOUT == proto.get_send_timeout());

    proto.set_recv_timeout(10);
    EXPECT_TRUE(10 == proto.get_recv_timeout());

    proto.set_send_timeout(10);
    EXPECT_TRUE(10 == proto.get_send_timeout());
}

/**
* get recv/send bytes of protocol stack.
*/
TEST(ProtocolStackTest, ProtocolBytes) {
    MockBufferIO bio;
    SrsProtocol proto(&bio);

    EXPECT_TRUE(0 == proto.get_recv_bytes());
    EXPECT_TRUE(0 == proto.get_send_bytes());

    SrsConnectAppPacket* pkt = new SrsConnectAppPacket();
    EXPECT_TRUE(ERROR_SUCCESS == proto.send_and_free_packet(pkt, 0));
    EXPECT_TRUE(0 < proto.get_send_bytes());
}

/**
* recv a SrsConnectAppPacket packet.
*/
TEST(ProtocolStackTest, ProtocolRecvMessage) {
    MockBufferIO bio;
    SrsProtocol proto(&bio);

    // packet is SrsConnectAppPacket
    char data[] = {
        // 12bytes header, 1byts chunk header, 11bytes msg heder
        (char)0x03, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x01, (char)0xa1, (char)0x14, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        // msg payload start
        (char)0x02, (char)0x00, (char)0x07, (char)0x63,
        (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
        (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
        (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
        (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
        (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
        (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
        (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
        (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c,
        (char)0xC3, /*next chunk.*/ (char)0x61, (char)0x79, (char)0x65, (char)0x72,
        (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
        (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
        (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
        (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
        (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
        (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        (char)0xC3, /*next chunk.*/ (char)0x0d, (char)0x76, (char)0x69, (char)0x64,
        (char)0x65, (char)0x6f, (char)0x46, (char)0x75, (char)0x6e, (char)0x63, (char)0x74, (char)0x69, (char)0x6f, (char)0x6e, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x07, (char)0x70, (char)0x61, (char)0x67, (char)0x65, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x62, (char)0x68,
        (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72, (char)0x73, (char)0x2e,
        (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x73,
        (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2e, (char)0x68, (char)0x74, (char)0x6d, (char)0x6c,
        (char)0x3f, (char)0x76, (char)0x68, (char)0x6f, (char)0x73, (char)0x74, (char)0x3d, (char)0x64, (char)0x65, (char)0x76, (char)0x26, (char)0x73, (char)0x74, (char)0x72, (char)0x65, (char)0x61,
        (char)0x6d, (char)0x3d, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x73, (char)0x74, (char)0x72, (char)0x65, (char)0x61, (char)0x6d, (char)0x26, (char)0x73, (char)0x65, (char)0x72,
        (char)0x76, (char)0x65, (char)0x72, (char)0x3d, (char)0x64, (char)0x65, (char)0x76, (char)0x26, (char)0x70, (char)0x6f, (char)0x72, (char)0x74,
        (char)0xC3, /*next chunk.*/ (char)0x3d, (char)0x31, (char)0x39, (char)0x33,
        (char)0x35, (char)0x00, (char)0x0e, (char)0x6f, (char)0x62, (char)0x6a, (char)0x65, (char)0x63, (char)0x74, (char)0x45, (char)0x6e, (char)0x63, (char)0x6f, (char)0x64, (char)0x69, (char)0x6e,
        (char)0x67, (char)0x00, (char)0x40, (char)0x08, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x09
    };
    bio.in_buffer.append(data, sizeof(data));

    SrsCommonMessage* msg = NULL;
    ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
    SrsAutoFree(SrsCommonMessage, msg);

    SrsPacket* pkt = NULL;
    EXPECT_TRUE(ERROR_SUCCESS == proto.decode_message(msg, &pkt));
    SrsAutoFree(SrsPacket, pkt);

    SrsConnectAppPacket* spkt = dynamic_cast<SrsConnectAppPacket*>(pkt);
    ASSERT_TRUE(NULL != spkt);
}

// for librtmp, if ping, it will send a fresh stream with fmt=1,
// 0x42             where: fmt=1, cid=2, protocol contorl user-control message
// 0x00 0x00 0x00   where: timestamp=0
// 0x00 0x00 0x06   where: payload_length=6
// 0x04             where: message_type=4(protocol control user-control message)
// 0x00 0x06            where: event Ping(0x06)
// 0x00 0x00 0x0d 0x0f  where: event data 4bytes ping timestamp.
TEST(ProtocolStackTest, ProtocolRecvMessageBug98) {
    MockBufferIO bio;
    SrsProtocol proto(&bio);

    // packet is SrsConnectAppPacket
    char data[] = {
        (char)0x42, // 1bytes chunk header
        (char)0x00, (char)0x00, (char)0x00, // timestamp=0
        (char)0x00, (char)0x00, (char)0x06, // payload_length=6
        (char)0x04, // message_type=4(protocol control user-control message)
        (char)0x00, (char)0x06, // event Ping(0x06)
        (char)0x00, (char)0x00, (char)0x0d, (char)0x0f // event data 4bytes ping timestamp.
    };
    bio.in_buffer.append(data, sizeof(data));

    SrsCommonMessage* msg = NULL;
    ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
    SrsAutoFree(SrsCommonMessage, msg);

    SrsPacket* pkt = NULL;
    EXPECT_TRUE(ERROR_SUCCESS == proto.decode_message(msg, &pkt));
    SrsAutoFree(SrsPacket, pkt);

    SrsUserControlPacket* spkt = dynamic_cast<SrsUserControlPacket*>(pkt);
    ASSERT_TRUE(NULL != spkt);
    EXPECT_EQ(SrcPCUCPingRequest, spkt->event_type);
    EXPECT_EQ(0x0d0f, spkt->event_data);
}

/**
* recv a SrsSetWindowAckSizePacket packet.
*/
TEST(ProtocolStackTest, ProtocolRecvAckSizeMessage) {
    MockBufferIO bio;
    SrsProtocol proto(&bio);

    // packet is SrsSetWindowAckSizePacket
    char data[] = {
        // 12bytes header, 1byts chunk header, 11bytes msg heder
        (char)0x02,
        (char)0x00, (char)0x00, (char)0x00,
        (char)0x00, (char)0x00, (char)0x04,
        (char)0x05,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        // msg payload start
        (char)0x00, (char)0x00, (char)0x07, (char)0x63
    };
    bio.in_buffer.append(data, sizeof(data));

    SrsCommonMessage* msg = NULL;
    ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
    SrsAutoFree(SrsCommonMessage, msg);

    SrsPacket* pkt = NULL;
    EXPECT_TRUE(ERROR_SUCCESS == proto.decode_message(msg, &pkt));
    SrsAutoFree(SrsPacket, pkt);

    SrsSetWindowAckSizePacket* spkt = dynamic_cast<SrsSetWindowAckSizePacket*>(pkt);
    ASSERT_TRUE(NULL != spkt);
    EXPECT_EQ(0x0763, spkt->ackowledgement_window_size);
}

/**
* recv a video message.
*/
TEST(ProtocolStackTest, ProtocolRecvVMessage) {
    MockBufferIO bio;
    SrsProtocol proto(&bio);

    // video message
    char data[] = {
        // 12bytes header, 1byts chunk header, 11bytes msg heder
        (char)0x03,
        (char)0x00, (char)0x00, (char)0x00, // timestamp
        (char)0x00, (char)0x00, (char)0x04, // length
        (char)0x09, // message_type
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, // stream_id
        // msg payload start
        (char)0x00, (char)0x00, (char)0x07, (char)0x63
    };
    bio.in_buffer.append(data, sizeof(data));

    SrsCommonMessage* msg = NULL;
    ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
    SrsAutoFree(SrsCommonMessage, msg);
    EXPECT_TRUE(msg->header.is_video());
}

/**
* recv a audio message.
*/
TEST(ProtocolStackTest, ProtocolRecvAMessage) {
    MockBufferIO bio;
    SrsProtocol proto(&bio);

    // audio message
    char data[] = {
        // 12bytes header, 1byts chunk header, 11bytes msg heder
        (char)0x03,
        (char)0x00, (char)0x00, (char)0x00, // timestamp
        (char)0x00, (char)0x00, (char)0x04, // length
        (char)0x08, // message_type
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, // stream_id
        // msg payload start
        (char)0x00, (char)0x00, (char)0x07, (char)0x63
    };
    bio.in_buffer.append(data, sizeof(data));

    SrsCommonMessage* msg = NULL;
    ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
    SrsAutoFree(SrsCommonMessage, msg);
    EXPECT_TRUE(msg->header.is_audio());
}

/**
* recv a video message in 2 chunk packets.
*/
TEST(ProtocolStackTest, ProtocolRecvVMessage2Trunk) {
    MockBufferIO bio;
    SrsProtocol proto(&bio);

    // video message
    char data[] = {
        // 12bytes header, 1byts chunk header, 11bytes msg heder
        (char)0x03,
        (char)0x00, (char)0x00, (char)0x00, // timestamp
        (char)0x00, (char)0x01, (char)0x10, // length, 272
        (char)0x09, // message_type
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, // stream_id
        // msg payload start
        (char)0x02, (char)0x00, (char)0x07, (char)0x63,
        (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
        (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
        (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
        (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
        (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
        (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
        (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
        (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c,
        (char)0xC3, /*next chunk.*/ (char)0x61, (char)0x79, (char)0x65, (char)0x72,
        (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
        (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
        (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
        (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
        (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
        (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        (char)0xC3, /*next chunk.*/
        (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
    };
    bio.in_buffer.append(data, sizeof(data));

    SrsCommonMessage* msg = NULL;
    ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
    SrsAutoFree(SrsCommonMessage, msg);
    EXPECT_TRUE(msg->header.is_video());
}

/**
* recv video and audio, interlaced in chunks.
*/
TEST(ProtocolStackTest, ProtocolRecvVAMessage) {
    MockBufferIO bio;
    SrsProtocol proto(&bio);

    // video message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x03,
            (char)0x00, (char)0x00, (char)0x00, // timestamp
            (char)0x00, (char)0x01, (char)0x10, // length, 272
            (char)0x09, // message_type
            (char)0x00, (char)0x00, (char)0x00, (char)0x00, // stream_id
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // audio message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x04,
            (char)0x00, (char)0x00, (char)0x00, // timestamp
            (char)0x00, (char)0x00, (char)0x90, // length, 144
            (char)0x08, // message_type
            (char)0x00, (char)0x00, (char)0x00, (char)0x00, // stream_id
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#2
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/ (char)0x61, (char)0x79, (char)0x65, (char)0x72,
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
            (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
            (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
            (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
            (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
            (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
            (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
            (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // audio message, chunk#2
    if (true) {
        char data[] = {
            (char)0xC4, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#3
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }

    if (true) {
        SrsCommonMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsCommonMessage, msg);
        EXPECT_TRUE(msg->header.is_audio());
    }
    if (true) {
        SrsCommonMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsCommonMessage, msg);
        EXPECT_TRUE(msg->header.is_video());
    }
}

/**
* recv video and audio, interlaced in chunks.
* the continue chunks use fmt=1 header
*/
TEST(ProtocolStackTest, ProtocolRecvVAFmt1) {
    MockBufferIO bio;
    SrsProtocol proto(&bio);

    /**
    * parse the message header.
    *   3bytes: timestamp delta,    fmt=0,1,2
    *   3bytes: payload length,     fmt=0,1
    *   1bytes: message type,       fmt=0,1
    *   4bytes: stream id,          fmt=0
    * where:
    *   fmt=0, 0x0X
    *   fmt=1, 0x4X
    *   fmt=2, 0x8X
    *   fmt=3, 0xCX
    */

    // video message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x03,
            (char)0x00, (char)0x00, (char)0x00, // timestamp
            (char)0x00, (char)0x01, (char)0x10, // length, 272
            (char)0x09, // message_type
            (char)0x00, (char)0x00, (char)0x00, (char)0x00, // stream_id
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // audio message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x04,
            (char)0x00, (char)0x00, (char)0x00, // timestamp
            (char)0x00, (char)0x00, (char)0x90, // length, 144
            (char)0x08, // message_type
            (char)0x00, (char)0x00, (char)0x00, (char)0x00, // stream_id
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#2
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x43,
            (char)0x00, (char)0x00, (char)0x00, // timestamp
            (char)0x00, (char)0x01, (char)0x10, // length, 272
            (char)0x09, // message_type
            // msg payload start
            /*next chunk.*/ (char)0x61, (char)0x79, (char)0x65, (char)0x72,
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
            (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
            (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
            (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
            (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
            (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
            (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
            (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // audio message, chunk#2
    if (true) {
        char data[] = {
            (char)0xC4, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#3
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }

    if (true) {
        SrsCommonMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsCommonMessage, msg);
        EXPECT_TRUE(msg->header.is_audio());
    }
    if (true) {
        SrsCommonMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsCommonMessage, msg);
        EXPECT_TRUE(msg->header.is_video());
    }
}

/**
* recv video and audio, interlaced in chunks.
* the continue chunks use fmt=2 header
*/
TEST(ProtocolStackTest, ProtocolRecvVAFmt2) {
    MockBufferIO bio;
    SrsProtocol proto(&bio);

    /**
    * parse the message header.
    *   3bytes: timestamp delta,    fmt=0,1,2
    *   3bytes: payload length,     fmt=0,1
    *   1bytes: message type,       fmt=0,1
    *   4bytes: stream id,          fmt=0
    * where:
    *   fmt=0, 0x0X
    *   fmt=1, 0x4X
    *   fmt=2, 0x8X
    *   fmt=3, 0xCX
    */

    // video message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x03,
            (char)0x00, (char)0x00, (char)0x00, // timestamp
            (char)0x00, (char)0x01, (char)0x10, // length, 272
            (char)0x09, // message_type
            (char)0x00, (char)0x00, (char)0x00, (char)0x00, // stream_id
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // audio message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x04,
            (char)0x00, (char)0x00, (char)0x00, // timestamp
            (char)0x00, (char)0x00, (char)0x90, // length, 144
            (char)0x08, // message_type
            (char)0x00, (char)0x00, (char)0x00, (char)0x00, // stream_id
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#2
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x83,
            (char)0x00, (char)0x00, (char)0x00, // timestamp
            // msg payload start
            /*next chunk.*/ (char)0x61, (char)0x79, (char)0x65, (char)0x72,
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
            (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
            (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
            (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
            (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
            (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
            (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
            (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // audio message, chunk#2
    if (true) {
        char data[] = {
            (char)0xC4, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#3
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }

    if (true) {
        SrsCommonMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsCommonMessage, msg);
        EXPECT_TRUE(msg->header.is_audio());
    }
    if (true) {
        SrsCommonMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsCommonMessage, msg);
        EXPECT_TRUE(msg->header.is_video());
    }
}

/**
* recv video and audio, interlaced in chunks.
* the continue chunks use fmt=3 header
*/
TEST(ProtocolStackTest, ProtocolRecvVAFmt3) {
    MockBufferIO bio;
    SrsProtocol proto(&bio);

    /**
    * parse the message header.
    *   3bytes: timestamp delta,    fmt=0,1,2
    *   3bytes: payload length,     fmt=0,1
    *   1bytes: message type,       fmt=0,1
    *   4bytes: stream id,          fmt=0
    * where:
    *   fmt=0, 0x0X
    *   fmt=1, 0x4X
    *   fmt=2, 0x8X
    *   fmt=3, 0xCX
    */

    // video message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x03,
            (char)0x00, (char)0x00, (char)0x00, // timestamp
            (char)0x00, (char)0x01, (char)0x10, // length, 272
            (char)0x09, // message_type
            (char)0x00, (char)0x00, (char)0x00, (char)0x00, // stream_id
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // audio message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x04,
            (char)0x00, (char)0x00, (char)0x00, // timestamp
            (char)0x00, (char)0x00, (char)0x90, // length, 144
            (char)0x08, // message_type
            (char)0x00, (char)0x00, (char)0x00, (char)0x00, // stream_id
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#2
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0xC3,
            // msg payload start
            /*next chunk.*/ (char)0x61, (char)0x79, (char)0x65, (char)0x72,
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
            (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
            (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
            (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
            (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
            (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
            (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
            (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // audio message, chunk#2
    if (true) {
        char data[] = {
            (char)0xC4, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#3
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }

    if (true) {
        SrsCommonMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsCommonMessage, msg);
        EXPECT_TRUE(msg->header.is_audio());
    }
    if (true) {
        SrsCommonMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsCommonMessage, msg);
        EXPECT_TRUE(msg->header.is_video());
    }
}

/**
* recv video, audio and video, interlaced in chunks.
*/
TEST(ProtocolStackTest, ProtocolRecvVAVMessage) {
    MockBufferIO bio;
    SrsProtocol proto(&bio);

    // video message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x03,
            (char)0x00, (char)0x00, (char)0x10, // timestamp
            (char)0x00, (char)0x01, (char)0x10, // length, 272
            (char)0x09, // message_type
            (char)0x01, (char)0x00, (char)0x00, (char)0x00, // stream_id
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // audio message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x04,
            (char)0x00, (char)0x00, (char)0x15, // timestamp
            (char)0x00, (char)0x00, (char)0x90, // length, 144
            (char)0x08, // message_type
            (char)0x01, (char)0x00, (char)0x00, (char)0x00, // stream_id
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#2
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/ (char)0x61, (char)0x79, (char)0x65, (char)0x72,
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
            (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
            (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
            (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
            (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
            (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
            (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
            (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#3
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x03,
            (char)0x00, (char)0x00, (char)0x20, // timestamp
            (char)0x00, (char)0x01, (char)0x10, // length, 272
            (char)0x09, // message_type
            (char)0x01, (char)0x00, (char)0x00, (char)0x00, // stream_id
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#2
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/ (char)0x61, (char)0x79, (char)0x65, (char)0x72,
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
            (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
            (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
            (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
            (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
            (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
            (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
            (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // audio message, chunk#2
    if (true) {
        char data[] = {
            (char)0xC4, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#3
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }

    if (true) {
        SrsCommonMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsCommonMessage, msg);
        EXPECT_TRUE(msg->header.is_video());
        EXPECT_EQ(0x10, msg->header.timestamp);
        EXPECT_EQ(0x01, msg->header.stream_id);
    }
    if (true) {
        SrsCommonMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsCommonMessage, msg);
        EXPECT_TRUE(msg->header.is_audio());
        EXPECT_EQ(0x15, msg->header.timestamp);
        EXPECT_EQ(0x01, msg->header.stream_id);
    }
    if (true) {
        SrsCommonMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsCommonMessage, msg);
        EXPECT_TRUE(msg->header.is_video());
        EXPECT_EQ(0x20, msg->header.timestamp);
        EXPECT_EQ(0x01, msg->header.stream_id);
    }
}

/**
* recv video, audio and video, interlaced in chunks.
* the continue chunks use fmt=1 header
*/
TEST(ProtocolStackTest, ProtocolRecvVAVFmt1) {
    MockBufferIO bio;
    SrsProtocol proto(&bio);

    /**
    * parse the message header.
    *   3bytes: timestamp delta,    fmt=0,1,2
    *   3bytes: payload length,     fmt=0,1
    *   1bytes: message type,       fmt=0,1
    *   4bytes: stream id,          fmt=0
    * where:
    *   fmt=0, 0x0X
    *   fmt=1, 0x4X
    *   fmt=2, 0x8X
    *   fmt=3, 0xCX
    */

    // video message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x03,
            (char)0x00, (char)0x00, (char)0x10, // timestamp
            (char)0x00, (char)0x01, (char)0x10, // length, 272
            (char)0x09, // message_type
            (char)0x01, (char)0x00, (char)0x00, (char)0x00, // stream_id
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // audio message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x04,
            (char)0x00, (char)0x00, (char)0x15, // timestamp
            (char)0x00, (char)0x00, (char)0x90, // length, 144
            (char)0x08, // message_type
            (char)0x01, (char)0x00, (char)0x00, (char)0x00, // stream_id
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#2
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/ (char)0x61, (char)0x79, (char)0x65, (char)0x72,
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
            (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
            (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
            (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
            (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
            (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
            (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
            (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#3
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x43,
            (char)0x00, (char)0x00, (char)0x12, // timestamp
            (char)0x00, (char)0x01, (char)0x10, // length, 272
            (char)0x09, // message_type
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#2
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/ (char)0x61, (char)0x79, (char)0x65, (char)0x72,
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
            (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
            (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
            (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
            (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
            (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
            (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
            (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // audio message, chunk#2
    if (true) {
        char data[] = {
            (char)0xC4, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#3
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }

    if (true) {
        SrsCommonMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsCommonMessage, msg);
        EXPECT_TRUE(msg->header.is_video());
        EXPECT_EQ(0x10, msg->header.timestamp);
        EXPECT_EQ(0x01, msg->header.stream_id);
    }
    if (true) {
        SrsCommonMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsCommonMessage, msg);
        EXPECT_TRUE(msg->header.is_audio());
        EXPECT_EQ(0x15, msg->header.timestamp);
        EXPECT_EQ(0x01, msg->header.stream_id);
    }
    if (true) {
        SrsCommonMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsCommonMessage, msg);
        EXPECT_TRUE(msg->header.is_video());
        EXPECT_EQ(0x22, msg->header.timestamp);
        EXPECT_EQ(0x01, msg->header.stream_id);
    }
}

/**
* recv video, audio and video, interlaced in chunks.
* the continue chunks use fmt=2 header
*/
TEST(ProtocolStackTest, ProtocolRecvVAVFmt2) {
    MockBufferIO bio;
    SrsProtocol proto(&bio);

    /**
    * parse the message header.
    *   3bytes: timestamp delta,    fmt=0,1,2
    *   3bytes: payload length,     fmt=0,1
    *   1bytes: message type,       fmt=0,1
    *   4bytes: stream id,          fmt=0
    * where:
    *   fmt=0, 0x0X
    *   fmt=1, 0x4X
    *   fmt=2, 0x8X
    *   fmt=3, 0xCX
    */

    // video message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x03,
            (char)0x00, (char)0x00, (char)0x10, // timestamp
            (char)0x00, (char)0x01, (char)0x10, // length, 272
            (char)0x09, // message_type
            (char)0x01, (char)0x00, (char)0x00, (char)0x00, // stream_id
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // audio message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x04,
            (char)0x00, (char)0x00, (char)0x15, // timestamp
            (char)0x00, (char)0x00, (char)0x90, // length, 144
            (char)0x08, // message_type
            (char)0x01, (char)0x00, (char)0x00, (char)0x00, // stream_id
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#2
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/ (char)0x61, (char)0x79, (char)0x65, (char)0x72,
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
            (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
            (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
            (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
            (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
            (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
            (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
            (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#3
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x83,
            (char)0x00, (char)0x00, (char)0x12, // timestamp
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#2
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/ (char)0x61, (char)0x79, (char)0x65, (char)0x72,
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
            (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
            (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
            (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
            (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
            (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
            (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
            (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // audio message, chunk#2
    if (true) {
        char data[] = {
            (char)0xC4, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#3
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }

    if (true) {
        SrsCommonMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsCommonMessage, msg);
        EXPECT_TRUE(msg->header.is_video());
        EXPECT_EQ(0x10, msg->header.timestamp);
        EXPECT_EQ(0x01, msg->header.stream_id);
    }
    if (true) {
        SrsCommonMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsCommonMessage, msg);
        EXPECT_TRUE(msg->header.is_audio());
        EXPECT_EQ(0x15, msg->header.timestamp);
        EXPECT_EQ(0x01, msg->header.stream_id);
    }
    if (true) {
        SrsCommonMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsCommonMessage, msg);
        EXPECT_TRUE(msg->header.is_video());
        EXPECT_EQ(0x22, msg->header.timestamp);
        EXPECT_EQ(0x01, msg->header.stream_id);
    }
}

/**
* recv video, audio and video, interlaced in chunks.
* the continue chunks use fmt=3 header
*/
TEST(ProtocolStackTest, ProtocolRecvVAVFmt3) {
    MockBufferIO bio;
    SrsProtocol proto(&bio);

    /**
    * parse the message header.
    *   3bytes: timestamp delta,    fmt=0,1,2
    *   3bytes: payload length,     fmt=0,1
    *   1bytes: message type,       fmt=0,1
    *   4bytes: stream id,          fmt=0
    * where:
    *   fmt=0, 0x0X
    *   fmt=1, 0x4X
    *   fmt=2, 0x8X
    *   fmt=3, 0xCX
    */

    // video message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x03,
            (char)0x00, (char)0x00, (char)0x10, // timestamp
            (char)0x00, (char)0x01, (char)0x10, // length, 272
            (char)0x09, // message_type
            (char)0x01, (char)0x00, (char)0x00, (char)0x00, // stream_id
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // audio message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x04,
            (char)0x00, (char)0x00, (char)0x15, // timestamp
            (char)0x00, (char)0x00, (char)0x90, // length, 144
            (char)0x08, // message_type
            (char)0x01, (char)0x00, (char)0x00, (char)0x00, // stream_id
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#2
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/ (char)0x61, (char)0x79, (char)0x65, (char)0x72,
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
            (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
            (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
            (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
            (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
            (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
            (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
            (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#3
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0xC3,
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#2
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/ (char)0x61, (char)0x79, (char)0x65, (char)0x72,
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
            (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
            (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
            (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
            (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
            (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
            (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
            (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // audio message, chunk#2
    if (true) {
        char data[] = {
            (char)0xC4, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#3
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }

    if (true) {
        SrsCommonMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsCommonMessage, msg);
        EXPECT_TRUE(msg->header.is_video());
        EXPECT_EQ(0x10, msg->header.timestamp);
        EXPECT_EQ(0x01, msg->header.stream_id);
    }
    if (true) {
        SrsCommonMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsCommonMessage, msg);
        EXPECT_TRUE(msg->header.is_audio());
        EXPECT_EQ(0x15, msg->header.timestamp);
        EXPECT_EQ(0x01, msg->header.stream_id);
    }
    if (true) {
        SrsCommonMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsCommonMessage, msg);
        EXPECT_TRUE(msg->header.is_video());
        EXPECT_EQ(0x20, msg->header.timestamp);
        EXPECT_EQ(0x01, msg->header.stream_id);
    }
}

/**
* recv video, audio, video and video, interlaced in chunks.
*/
TEST(ProtocolStackTest, ProtocolRecvVAVVMessage) {
    MockBufferIO bio;
    SrsProtocol proto(&bio);

    // video message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x03,
            (char)0x00, (char)0x00, (char)0x10, // timestamp
            (char)0x00, (char)0x01, (char)0x10, // length, 272
            (char)0x09, // message_type
            (char)0x01, (char)0x00, (char)0x00, (char)0x00, // stream_id
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // audio message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x04,
            (char)0x00, (char)0x00, (char)0x15, // timestamp
            (char)0x00, (char)0x00, (char)0x90, // length, 144
            (char)0x08, // message_type
            (char)0x01, (char)0x00, (char)0x00, (char)0x00, // stream_id
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#2
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/ (char)0x61, (char)0x79, (char)0x65, (char)0x72,
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
            (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
            (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
            (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
            (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
            (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
            (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
            (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#3
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x03,
            (char)0x00, (char)0x00, (char)0x20, // timestamp
            (char)0x00, (char)0x01, (char)0x10, // length, 272
            (char)0x09, // message_type
            (char)0x01, (char)0x00, (char)0x00, (char)0x00, // stream_id
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#2
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/ (char)0x61, (char)0x79, (char)0x65, (char)0x72,
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
            (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
            (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
            (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
            (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
            (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
            (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
            (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // audio message, chunk#2
    if (true) {
        char data[] = {
            (char)0xC4, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#3
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x03,
            (char)0x00, (char)0x00, (char)0x30, // timestamp
            (char)0x00, (char)0x01, (char)0x10, // length, 272
            (char)0x09, // message_type
            (char)0x01, (char)0x00, (char)0x00, (char)0x00, // stream_id
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#2
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/ (char)0x61, (char)0x79, (char)0x65, (char)0x72,
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
            (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
            (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
            (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
            (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
            (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
            (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
            (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#3
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }

    if (true) {
        SrsCommonMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsCommonMessage, msg);
        EXPECT_TRUE(msg->header.is_video());
        EXPECT_EQ(0x10, msg->header.timestamp);
        EXPECT_EQ(0x01, msg->header.stream_id);
    }
    if (true) {
        SrsCommonMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsCommonMessage, msg);
        EXPECT_TRUE(msg->header.is_audio());
        EXPECT_EQ(0x15, msg->header.timestamp);
        EXPECT_EQ(0x01, msg->header.stream_id);
    }
    if (true) {
        SrsCommonMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsCommonMessage, msg);
        EXPECT_TRUE(msg->header.is_video());
        EXPECT_EQ(0x20, msg->header.timestamp);
        EXPECT_EQ(0x01, msg->header.stream_id);
    }
    if (true) {
        SrsCommonMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsCommonMessage, msg);
        EXPECT_TRUE(msg->header.is_video());
        EXPECT_EQ(0x30, msg->header.timestamp);
        EXPECT_EQ(0x01, msg->header.stream_id);
    }
}

/**
* recv video, audio, video and video, interlaced in chunks.
* the continue chunks use fmt=1 header
*/
TEST(ProtocolStackTest, ProtocolRecvVAVVFmt1) {
    MockBufferIO bio;
    SrsProtocol proto(&bio);

    /**
    * parse the message header.
    *   3bytes: timestamp delta,    fmt=0,1,2
    *   3bytes: payload length,     fmt=0,1
    *   1bytes: message type,       fmt=0,1
    *   4bytes: stream id,          fmt=0
    * where:
    *   fmt=0, 0x0X
    *   fmt=1, 0x4X
    *   fmt=2, 0x8X
    *   fmt=3, 0xCX
    */

    // video message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x03,
            (char)0x00, (char)0x00, (char)0x10, // timestamp
            (char)0x00, (char)0x01, (char)0x10, // length, 272
            (char)0x09, // message_type
            (char)0x01, (char)0x00, (char)0x00, (char)0x00, // stream_id
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // audio message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x04,
            (char)0x00, (char)0x00, (char)0x15, // timestamp
            (char)0x00, (char)0x00, (char)0x90, // length, 144
            (char)0x08, // message_type
            (char)0x01, (char)0x00, (char)0x00, (char)0x00, // stream_id
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#2
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/ (char)0x61, (char)0x79, (char)0x65, (char)0x72,
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
            (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
            (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
            (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
            (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
            (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
            (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
            (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#3
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x43,
            (char)0x00, (char)0x00, (char)0x10, // timestamp
            (char)0x00, (char)0x01, (char)0x10, // length, 272
            (char)0x09, // message_type
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#2
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/ (char)0x61, (char)0x79, (char)0x65, (char)0x72,
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
            (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
            (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
            (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
            (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
            (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
            (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
            (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // audio message, chunk#2
    if (true) {
        char data[] = {
            (char)0xC4, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#3
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x43,
            (char)0x00, (char)0x00, (char)0x10, // timestamp
            (char)0x00, (char)0x01, (char)0x10, // length, 272
            (char)0x09, // message_type
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#2
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/ (char)0x61, (char)0x79, (char)0x65, (char)0x72,
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
            (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
            (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
            (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
            (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
            (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
            (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
            (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#3
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }

    if (true) {
        SrsCommonMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsCommonMessage, msg);
        EXPECT_TRUE(msg->header.is_video());
        EXPECT_EQ(0x10, msg->header.timestamp);
        EXPECT_EQ(0x01, msg->header.stream_id);
    }
    if (true) {
        SrsCommonMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsCommonMessage, msg);
        EXPECT_TRUE(msg->header.is_audio());
        EXPECT_EQ(0x15, msg->header.timestamp);
        EXPECT_EQ(0x01, msg->header.stream_id);
    }
    if (true) {
        SrsCommonMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsCommonMessage, msg);
        EXPECT_TRUE(msg->header.is_video());
        EXPECT_EQ(0x20, msg->header.timestamp);
        EXPECT_EQ(0x01, msg->header.stream_id);
    }
    if (true) {
        SrsCommonMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsCommonMessage, msg);
        EXPECT_TRUE(msg->header.is_video());
        EXPECT_EQ(0x30, msg->header.timestamp);
        EXPECT_EQ(0x01, msg->header.stream_id);
    }
}

/**
* recv video, audio, video and video, interlaced in chunks.
* the continue chunks use fmt=2 header
*/
TEST(ProtocolStackTest, ProtocolRecvVAVVFmt2) {
    MockBufferIO bio;
    SrsProtocol proto(&bio);

    /**
    * parse the message header.
    *   3bytes: timestamp delta,    fmt=0,1,2
    *   3bytes: payload length,     fmt=0,1
    *   1bytes: message type,       fmt=0,1
    *   4bytes: stream id,          fmt=0
    * where:
    *   fmt=0, 0x0X
    *   fmt=1, 0x4X
    *   fmt=2, 0x8X
    *   fmt=3, 0xCX
    */

    // video message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x03,
            (char)0x00, (char)0x00, (char)0x10, // timestamp
            (char)0x00, (char)0x01, (char)0x10, // length, 272
            (char)0x09, // message_type
            (char)0x01, (char)0x00, (char)0x00, (char)0x00, // stream_id
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // audio message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x04,
            (char)0x00, (char)0x00, (char)0x15, // timestamp
            (char)0x00, (char)0x00, (char)0x90, // length, 144
            (char)0x08, // message_type
            (char)0x01, (char)0x00, (char)0x00, (char)0x00, // stream_id
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#2
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/ (char)0x61, (char)0x79, (char)0x65, (char)0x72,
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
            (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
            (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
            (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
            (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
            (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
            (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
            (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#3
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x83,
            (char)0x00, (char)0x00, (char)0x10, // timestamp
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#2
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/ (char)0x61, (char)0x79, (char)0x65, (char)0x72,
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
            (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
            (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
            (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
            (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
            (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
            (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
            (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // audio message, chunk#2
    if (true) {
        char data[] = {
            (char)0xC4, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#3
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x83,
            (char)0x00, (char)0x00, (char)0x10, // timestamp
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#2
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/ (char)0x61, (char)0x79, (char)0x65, (char)0x72,
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
            (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
            (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
            (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
            (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
            (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
            (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
            (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#3
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }

    if (true) {
        SrsCommonMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsCommonMessage, msg);
        EXPECT_TRUE(msg->header.is_video());
        EXPECT_EQ(0x10, msg->header.timestamp);
        EXPECT_EQ(0x01, msg->header.stream_id);
    }
    if (true) {
        SrsCommonMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsCommonMessage, msg);
        EXPECT_TRUE(msg->header.is_audio());
        EXPECT_EQ(0x15, msg->header.timestamp);
        EXPECT_EQ(0x01, msg->header.stream_id);
    }
    if (true) {
        SrsCommonMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsCommonMessage, msg);
        EXPECT_TRUE(msg->header.is_video());
        EXPECT_EQ(0x20, msg->header.timestamp);
        EXPECT_EQ(0x01, msg->header.stream_id);
    }
    if (true) {
        SrsCommonMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsCommonMessage, msg);
        EXPECT_TRUE(msg->header.is_video());
        EXPECT_EQ(0x30, msg->header.timestamp);
        EXPECT_EQ(0x01, msg->header.stream_id);
    }
}

/**
* recv video, audio, video and video, interlaced in chunks.
* the continue chunks use fmt=3 header
*/
TEST(ProtocolStackTest, ProtocolRecvVAVVFmt3) {
    MockBufferIO bio;
    SrsProtocol proto(&bio);

    /**
    * parse the message header.
    *   3bytes: timestamp delta,    fmt=0,1,2
    *   3bytes: payload length,     fmt=0,1
    *   1bytes: message type,       fmt=0,1
    *   4bytes: stream id,          fmt=0
    * where:
    *   fmt=0, 0x0X
    *   fmt=1, 0x4X
    *   fmt=2, 0x8X
    *   fmt=3, 0xCX
    */

    // video message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x03,
            (char)0x00, (char)0x00, (char)0x10, // timestamp
            (char)0x00, (char)0x01, (char)0x10, // length, 272
            (char)0x09, // message_type
            (char)0x01, (char)0x00, (char)0x00, (char)0x00, // stream_id
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // audio message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x04,
            (char)0x00, (char)0x00, (char)0x15, // timestamp
            (char)0x00, (char)0x00, (char)0x90, // length, 144
            (char)0x08, // message_type
            (char)0x01, (char)0x00, (char)0x00, (char)0x00, // stream_id
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#2
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/ (char)0x61, (char)0x79, (char)0x65, (char)0x72,
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
            (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
            (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
            (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
            (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
            (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
            (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
            (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#3
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0xC3,
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#2
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/ (char)0x61, (char)0x79, (char)0x65, (char)0x72,
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
            (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
            (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
            (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
            (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
            (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
            (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
            (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // audio message, chunk#2
    if (true) {
        char data[] = {
            (char)0xC4, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#3
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0xC3,
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#2
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/ (char)0x61, (char)0x79, (char)0x65, (char)0x72,
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
            (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
            (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
            (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
            (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
            (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
            (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
            (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#3
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }

    if (true) {
        SrsCommonMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsCommonMessage, msg);
        EXPECT_TRUE(msg->header.is_video());
        EXPECT_EQ(0x10, msg->header.timestamp);
        EXPECT_EQ(0x01, msg->header.stream_id);
    }
    if (true) {
        SrsCommonMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsCommonMessage, msg);
        EXPECT_TRUE(msg->header.is_audio());
        EXPECT_EQ(0x15, msg->header.timestamp);
        EXPECT_EQ(0x01, msg->header.stream_id);
    }
    if (true) {
        SrsCommonMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsCommonMessage, msg);
        EXPECT_TRUE(msg->header.is_video());
        EXPECT_EQ(0x20, msg->header.timestamp);
        EXPECT_EQ(0x01, msg->header.stream_id);
    }
    if (true) {
        SrsCommonMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsCommonMessage, msg);
        EXPECT_TRUE(msg->header.is_video());
        EXPECT_EQ(0x30, msg->header.timestamp);
        EXPECT_EQ(0x01, msg->header.stream_id);
    }
}

/**
* recv video, audio, video and video, interlaced in chunks.
* the continue chunks use fmt=1, last video with fmt=1 header
*/
TEST(ProtocolStackTest, ProtocolRecvVAVVFmt11) {
    MockBufferIO bio;
    SrsProtocol proto(&bio);

    /**
    * parse the message header.
    *   3bytes: timestamp delta,    fmt=0,1,2
    *   3bytes: payload length,     fmt=0,1
    *   1bytes: message type,       fmt=0,1
    *   4bytes: stream id,          fmt=0
    * where:
    *   fmt=0, 0x0X
    *   fmt=1, 0x4X
    *   fmt=2, 0x8X
    *   fmt=3, 0xCX
    */

    // video message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x03,
            (char)0x00, (char)0x00, (char)0x10, // timestamp
            (char)0x00, (char)0x01, (char)0x10, // length, 272
            (char)0x09, // message_type
            (char)0x01, (char)0x00, (char)0x00, (char)0x00, // stream_id
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // audio message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x04,
            (char)0x00, (char)0x00, (char)0x15, // timestamp
            (char)0x00, (char)0x00, (char)0x90, // length, 144
            (char)0x08, // message_type
            (char)0x01, (char)0x00, (char)0x00, (char)0x00, // stream_id
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#2
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/ (char)0x61, (char)0x79, (char)0x65, (char)0x72,
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
            (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
            (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
            (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
            (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
            (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
            (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
            (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#3
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x43,
            (char)0x00, (char)0x00, (char)0x10, // timestamp
            (char)0x00, (char)0x01, (char)0x10, // length, 272
            (char)0x09, // message_type
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#2
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/ (char)0x61, (char)0x79, (char)0x65, (char)0x72,
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
            (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
            (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
            (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
            (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
            (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
            (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
            (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // audio message, chunk#2
    if (true) {
        char data[] = {
            (char)0xC4, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#3
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x43,
            (char)0x00, (char)0x00, (char)0x20, // timestamp
            (char)0x00, (char)0x01, (char)0x10, // length, 272
            (char)0x09, // message_type
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#2
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/ (char)0x61, (char)0x79, (char)0x65, (char)0x72,
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
            (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
            (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
            (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
            (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
            (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
            (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
            (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#3
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }

    if (true) {
        SrsCommonMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsCommonMessage, msg);
        EXPECT_TRUE(msg->header.is_video());
        EXPECT_EQ(0x10, msg->header.timestamp);
        EXPECT_EQ(0x01, msg->header.stream_id);
    }
    if (true) {
        SrsCommonMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsCommonMessage, msg);
        EXPECT_TRUE(msg->header.is_audio());
        EXPECT_EQ(0x15, msg->header.timestamp);
        EXPECT_EQ(0x01, msg->header.stream_id);
    }
    if (true) {
        SrsCommonMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsCommonMessage, msg);
        EXPECT_TRUE(msg->header.is_video());
        EXPECT_EQ(0x20, msg->header.timestamp);
        EXPECT_EQ(0x01, msg->header.stream_id);
    }
    if (true) {
        SrsCommonMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsCommonMessage, msg);
        EXPECT_TRUE(msg->header.is_video());
        EXPECT_EQ(0x40, msg->header.timestamp);
        EXPECT_EQ(0x01, msg->header.stream_id);
    }
}

/**
* recv video, audio, video and video, interlaced in chunks.
* the continue chunks use fmt=1, last video with fmt=1 header,
* last video changed length
*/
TEST(ProtocolStackTest, ProtocolRecvVAVVFmt11Length) {
    MockBufferIO bio;
    SrsProtocol proto(&bio);

    /**
    * parse the message header.
    *   3bytes: timestamp delta,    fmt=0,1,2
    *   3bytes: payload length,     fmt=0,1
    *   1bytes: message type,       fmt=0,1
    *   4bytes: stream id,          fmt=0
    * where:
    *   fmt=0, 0x0X
    *   fmt=1, 0x4X
    *   fmt=2, 0x8X
    *   fmt=3, 0xCX
    */

    // video message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x03,
            (char)0x00, (char)0x00, (char)0x10, // timestamp
            (char)0x00, (char)0x01, (char)0x10, // length, 272
            (char)0x09, // message_type
            (char)0x01, (char)0x00, (char)0x00, (char)0x00, // stream_id
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // audio message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x04,
            (char)0x00, (char)0x00, (char)0x15, // timestamp
            (char)0x00, (char)0x00, (char)0x90, // length, 144
            (char)0x08, // message_type
            (char)0x01, (char)0x00, (char)0x00, (char)0x00, // stream_id
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#2
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/ (char)0x61, (char)0x79, (char)0x65, (char)0x72,
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
            (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
            (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
            (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
            (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
            (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
            (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
            (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#3
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x43,
            (char)0x00, (char)0x00, (char)0x10, // timestamp
            (char)0x00, (char)0x01, (char)0x20, // length, 288
            (char)0x09, // message_type
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#2
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/ (char)0x61, (char)0x79, (char)0x65, (char)0x72,
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
            (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
            (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
            (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
            (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
            (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
            (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
            (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // audio message, chunk#2
    if (true) {
        char data[] = {
            (char)0xC4, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#3
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x43,
            (char)0x00, (char)0x00, (char)0x20, // timestamp
            (char)0x00, (char)0x01, (char)0x10, // length, 272
            (char)0x09, // message_type
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#2
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/ (char)0x61, (char)0x79, (char)0x65, (char)0x72,
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
            (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
            (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
            (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
            (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
            (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
            (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
            (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#3
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }

    if (true) {
        SrsCommonMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsCommonMessage, msg);
        EXPECT_TRUE(msg->header.is_video());
        EXPECT_EQ(0x10, msg->header.timestamp);
        EXPECT_EQ(0x01, msg->header.stream_id);
    }
    if (true) {
        SrsCommonMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsCommonMessage, msg);
        EXPECT_TRUE(msg->header.is_audio());
        EXPECT_EQ(0x15, msg->header.timestamp);
        EXPECT_EQ(0x01, msg->header.stream_id);
    }
    if (true) {
        SrsCommonMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsCommonMessage, msg);
        EXPECT_TRUE(msg->header.is_video());
        EXPECT_EQ(0x20, msg->header.timestamp);
        EXPECT_EQ(0x01, msg->header.stream_id);
    }
    if (true) {
        SrsCommonMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsCommonMessage, msg);
        EXPECT_TRUE(msg->header.is_video());
        EXPECT_EQ(0x40, msg->header.timestamp);
        EXPECT_EQ(0x01, msg->header.stream_id);
    }
}

/**
* recv video, audio, video and video, interlaced in chunks.
* the continue chunks use fmt=1, last video with fmt=2 header
*/
TEST(ProtocolStackTest, ProtocolRecvVAVVFmt12) {
    MockBufferIO bio;
    SrsProtocol proto(&bio);

    /**
    * parse the message header.
    *   3bytes: timestamp delta,    fmt=0,1,2
    *   3bytes: payload length,     fmt=0,1
    *   1bytes: message type,       fmt=0,1
    *   4bytes: stream id,          fmt=0
    * where:
    *   fmt=0, 0x0X
    *   fmt=1, 0x4X
    *   fmt=2, 0x8X
    *   fmt=3, 0xCX
    */

    // video message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x03,
            (char)0x00, (char)0x00, (char)0x10, // timestamp
            (char)0x00, (char)0x01, (char)0x10, // length, 272
            (char)0x09, // message_type
            (char)0x01, (char)0x00, (char)0x00, (char)0x00, // stream_id
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // audio message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x04,
            (char)0x00, (char)0x00, (char)0x15, // timestamp
            (char)0x00, (char)0x00, (char)0x90, // length, 144
            (char)0x08, // message_type
            (char)0x01, (char)0x00, (char)0x00, (char)0x00, // stream_id
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#2
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/ (char)0x61, (char)0x79, (char)0x65, (char)0x72,
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
            (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
            (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
            (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
            (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
            (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
            (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
            (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#3
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x43,
            (char)0x00, (char)0x00, (char)0x10, // timestamp
            (char)0x00, (char)0x01, (char)0x10, // length, 272
            (char)0x09, // message_type
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#2
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/ (char)0x61, (char)0x79, (char)0x65, (char)0x72,
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
            (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
            (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
            (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
            (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
            (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
            (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
            (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // audio message, chunk#2
    if (true) {
        char data[] = {
            (char)0xC4, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#3
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x83,
            (char)0x00, (char)0x00, (char)0x20, // timestamp
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#2
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/ (char)0x61, (char)0x79, (char)0x65, (char)0x72,
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
            (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
            (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
            (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
            (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
            (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
            (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
            (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#3
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }

    if (true) {
        SrsCommonMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsCommonMessage, msg);
        EXPECT_TRUE(msg->header.is_video());
        EXPECT_EQ(0x10, msg->header.timestamp);
        EXPECT_EQ(0x01, msg->header.stream_id);
    }
    if (true) {
        SrsCommonMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsCommonMessage, msg);
        EXPECT_TRUE(msg->header.is_audio());
        EXPECT_EQ(0x15, msg->header.timestamp);
        EXPECT_EQ(0x01, msg->header.stream_id);
    }
    if (true) {
        SrsCommonMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsCommonMessage, msg);
        EXPECT_TRUE(msg->header.is_video());
        EXPECT_EQ(0x20, msg->header.timestamp);
        EXPECT_EQ(0x01, msg->header.stream_id);
    }
    if (true) {
        SrsCommonMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsCommonMessage, msg);
        EXPECT_TRUE(msg->header.is_video());
        EXPECT_EQ(0x40, msg->header.timestamp);
        EXPECT_EQ(0x01, msg->header.stream_id);
    }
}

/**
* recv video, audio, video and video, interlaced in chunks.
* the continue chunks use fmt=1, last video with fmt=2 header,
* last video changed length
*/
TEST(ProtocolStackTest, ProtocolRecvVAVVFmt12Length) {
    MockBufferIO bio;
    SrsProtocol proto(&bio);

    /**
    * parse the message header.
    *   3bytes: timestamp delta,    fmt=0,1,2
    *   3bytes: payload length,     fmt=0,1
    *   1bytes: message type,       fmt=0,1
    *   4bytes: stream id,          fmt=0
    * where:
    *   fmt=0, 0x0X
    *   fmt=1, 0x4X
    *   fmt=2, 0x8X
    *   fmt=3, 0xCX
    */

    // video message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x03,
            (char)0x00, (char)0x00, (char)0x10, // timestamp
            (char)0x00, (char)0x01, (char)0x10, // length, 272
            (char)0x09, // message_type
            (char)0x01, (char)0x00, (char)0x00, (char)0x00, // stream_id
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // audio message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x04,
            (char)0x00, (char)0x00, (char)0x15, // timestamp
            (char)0x00, (char)0x00, (char)0x90, // length, 144
            (char)0x08, // message_type
            (char)0x01, (char)0x00, (char)0x00, (char)0x00, // stream_id
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#2
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/ (char)0x61, (char)0x79, (char)0x65, (char)0x72,
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
            (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
            (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
            (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
            (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
            (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
            (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
            (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#3
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x43,
            (char)0x00, (char)0x00, (char)0x10, // timestamp
            (char)0x00, (char)0x01, (char)0x20, // length, 288
            (char)0x09, // message_type
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#2
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/ (char)0x61, (char)0x79, (char)0x65, (char)0x72,
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
            (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
            (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
            (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
            (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
            (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
            (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
            (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // audio message, chunk#2
    if (true) {
        char data[] = {
            (char)0xC4, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#3
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x83,
            (char)0x00, (char)0x00, (char)0x20, // timestamp
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#2
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/ (char)0x61, (char)0x79, (char)0x65, (char)0x72,
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
            (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
            (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
            (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
            (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
            (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
            (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
            (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#3
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }

    if (true) {
        SrsCommonMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsCommonMessage, msg);
        EXPECT_TRUE(msg->header.is_video());
        EXPECT_EQ(0x10, msg->header.timestamp);
        EXPECT_EQ(0x01, msg->header.stream_id);
        EXPECT_EQ(0x110, msg->header.payload_length);
    }
    if (true) {
        SrsCommonMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsCommonMessage, msg);
        EXPECT_TRUE(msg->header.is_audio());
        EXPECT_EQ(0x15, msg->header.timestamp);
        EXPECT_EQ(0x01, msg->header.stream_id);
    }
    if (true) {
        SrsCommonMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsCommonMessage, msg);
        EXPECT_TRUE(msg->header.is_video());
        EXPECT_EQ(0x20, msg->header.timestamp);
        EXPECT_EQ(0x01, msg->header.stream_id);
        EXPECT_EQ(0x120, msg->header.payload_length);
    }
    if (true) {
        SrsCommonMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsCommonMessage, msg);
        EXPECT_TRUE(msg->header.is_video());
        EXPECT_EQ(0x40, msg->header.timestamp);
        EXPECT_EQ(0x01, msg->header.stream_id);
        EXPECT_EQ(0x120, msg->header.payload_length);
    }
}

/**
* recv video, with extended timestamp.
* small timestamp < 0xffffff
*/
TEST(ProtocolStackTest, ProtocolRecvExtTimeMessage) {
    MockBufferIO bio;
    SrsProtocol proto(&bio);

    /**
    * parse the message header.
    *   3bytes: timestamp delta,    fmt=0,1,2
    *   3bytes: payload length,     fmt=0,1
    *   1bytes: message type,       fmt=0,1
    *   4bytes: stream id,          fmt=0
    * where:
    *   fmt=0, 0x0X
    *   fmt=1, 0x4X
    *   fmt=2, 0x8X
    *   fmt=3, 0xCX
    */

    char data[] = {
        // 12bytes header, 1byts chunk header, 11bytes msg heder
        (char)0x03,
        (char)0xff, (char)0xff, (char)0xff, // timestamp
        (char)0x00, (char)0x00, (char)0x04, // length
        (char)0x09, // message_type
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, // stream_id
        (char)0x00, (char)0x00, (char)0x00, (char)0x10, // extended timestamp
        // msg payload start
        (char)0x00, (char)0x00, (char)0x07, (char)0x63
    };
    bio.in_buffer.append(data, sizeof(data));

    SrsCommonMessage* msg = NULL;
    ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
    SrsAutoFree(SrsCommonMessage, msg);
    EXPECT_TRUE(msg->header.is_video());
    EXPECT_EQ(0x10, msg->header.timestamp);
}

/**
* recv video, with extended timestamp.
* big timestamp > 0xffffff
*/
TEST(ProtocolStackTest, ProtocolRecvExtTimeMessage2) {
    MockBufferIO bio;
    SrsProtocol proto(&bio);

    /**
    * parse the message header.
    *   3bytes: timestamp delta,    fmt=0,1,2
    *   3bytes: payload length,     fmt=0,1
    *   1bytes: message type,       fmt=0,1
    *   4bytes: stream id,          fmt=0
    * where:
    *   fmt=0, 0x0X
    *   fmt=1, 0x4X
    *   fmt=2, 0x8X
    *   fmt=3, 0xCX
    */

    char data[] = {
        // 12bytes header, 1byts chunk header, 11bytes msg heder
        (char)0x03,
        (char)0xff, (char)0xff, (char)0xff, // timestamp
        (char)0x00, (char)0x00, (char)0x04, // length
        (char)0x09, // message_type
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, // stream_id
        (char)0x7f, (char)0x01, (char)0x02, (char)0x03, // extended timestamp
        // msg payload start
        (char)0x00, (char)0x00, (char)0x07, (char)0x63
    };
    bio.in_buffer.append(data, sizeof(data));

    SrsCommonMessage* msg = NULL;
    ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
    SrsAutoFree(SrsCommonMessage, msg);
    EXPECT_TRUE(msg->header.is_video());
    EXPECT_EQ(0x7f010203, msg->header.timestamp);
}

/**
* recv video, with extended timestamp.
* always use 31bits timestamp.
*/
// always use 31bits timestamp, for some server may use 32bits extended timestamp.
TEST(ProtocolStackTest, ProtocolRecvExtTimeMessage3) {
    MockBufferIO bio;
    SrsProtocol proto(&bio);

    /**
    * parse the message header.
    *   3bytes: timestamp delta,    fmt=0,1,2
    *   3bytes: payload length,     fmt=0,1
    *   1bytes: message type,       fmt=0,1
    *   4bytes: stream id,          fmt=0
    * where:
    *   fmt=0, 0x0X
    *   fmt=1, 0x4X
    *   fmt=2, 0x8X
    *   fmt=3, 0xCX
    */

    char data[] = {
        // 12bytes header, 1byts chunk header, 11bytes msg heder
        (char)0x03,
        (char)0xff, (char)0xff, (char)0xff, // timestamp
        (char)0x00, (char)0x00, (char)0x04, // length
        (char)0x09, // message_type
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, // stream_id
        (char)0xff, (char)0x01, (char)0x02, (char)0x03, // extended timestamp
        // msg payload start
        (char)0x00, (char)0x00, (char)0x07, (char)0x63
    };
    bio.in_buffer.append(data, sizeof(data));

    SrsCommonMessage* msg = NULL;
    ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
    SrsAutoFree(SrsCommonMessage, msg);
    EXPECT_TRUE(msg->header.is_video());
    // always use 31bits timestamp
    EXPECT_EQ(0x7f010203, msg->header.timestamp);
}

/**
* recv video, with extended timestamp, in 2 chunks packet.
* always send extended timestamp in 0xCX chunk packets.
*/
/**
* RTMP specification and ffmpeg/librtmp is false,
* but, adobe changed the specification, so flash/FMLE/FMS always true.
* default to true to support flash/FMLE/FMS.
*
* ffmpeg/librtmp may donot send this filed, need to detect the value.
* compare to the chunk timestamp, which is set by chunk message header
* type 0,1 or 2.
*
* @remark, nginx send the extended-timestamp in sequence-header,
* and timestamp delta in continue C1 chunks, and so compatible with ffmpeg,
* that is, there is no continue chunks and extended-timestamp in nginx-rtmp.
*
* @remark, srs always send the extended-timestamp, to keep simple,
* and compatible with adobe products.
*/
TEST(ProtocolStackTest, ProtocolRecvVExtTime2Trunk) {
    MockBufferIO bio;
    SrsProtocol proto(&bio);

    // video message
    char data[] = {
        // 12bytes header, 1byts chunk header, 11bytes msg heder
        (char)0x03,
        (char)0xff, (char)0xff, (char)0xff, // timestamp
        (char)0x00, (char)0x01, (char)0x10, // length, 272
        (char)0x09, // message_type
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, // stream_id
        (char)0x00, (char)0x01, (char)0x02, (char)0x03, // extended timestamp
        // msg payload start
        (char)0x02, (char)0x00, (char)0x07, (char)0x63,
        (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
        (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
        (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
        (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
        (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
        (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
        (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
        (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c,
        // chunk #2
        (char)0xC3,
        (char)0x00, (char)0x01, (char)0x02, (char)0x03, // extended timestamp
        /*next chunk.*/ (char)0x61, (char)0x79, (char)0x65, (char)0x72,
        (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
        (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
        (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
        (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
        (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
        (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        // chunk #2
        (char)0xC3,
        (char)0x00, (char)0x01, (char)0x02, (char)0x03, // extended timestamp
        /*next chunk.*/
        (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
    };
    bio.in_buffer.append(data, sizeof(data));

    SrsCommonMessage* msg = NULL;
    ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
    SrsAutoFree(SrsCommonMessage, msg);
    EXPECT_TRUE(msg->header.is_video());
    // 0xCX with extended timestamp.
    EXPECT_EQ(0x00010203, msg->header.timestamp);
}

/**
* recv video, with extended timestamp, in 2 chunks packet.
* never send extended timestamp in 0xCX chunk packets.
*/
// FFMPEG/librtmp, RTMP specification standard protocol.
TEST(ProtocolStackTest, ProtocolRecvVExtTime2Trunk2) {
    MockBufferIO bio;
    SrsProtocol proto(&bio);

    // video message
    char data[] = {
        // 12bytes header, 1byts chunk header, 11bytes msg heder
        (char)0x03,
        (char)0xff, (char)0xff, (char)0xff, // timestamp
        (char)0x00, (char)0x01, (char)0x10, // length, 272
        (char)0x09, // message_type
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, // stream_id
        (char)0x00, (char)0x01, (char)0x02, (char)0x03, // extended timestamp
        // msg payload start
        (char)0x02, (char)0x00, (char)0x07, (char)0x63,
        (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
        (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
        (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
        (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
        (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
        (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
        (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
        (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c,
        // chunk #2
        (char)0xC3,
        /*next chunk.*/ (char)0x61, (char)0x79, (char)0x65, (char)0x72,
        (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
        (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
        (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
        (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
        (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
        (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        // chunk #2
        (char)0xC3,
        /*next chunk.*/
        (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
    };
    bio.in_buffer.append(data, sizeof(data));

    SrsCommonMessage* msg = NULL;
    ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
    SrsAutoFree(SrsCommonMessage, msg);
    EXPECT_TRUE(msg->header.is_video());
    // 0xCX without extended timestamp.
    EXPECT_EQ(0x00010203, msg->header.timestamp);
}

/**
* a video message, in 2 chunks packet.
* use 1B chunk header, min chunk id is 2.
*/
TEST(ProtocolStackTest, ProtocolRecvVCid1BMin) {
    MockBufferIO bio;
    SrsProtocol proto(&bio);

    // video message
    char data[] = {
        // 12bytes header, 1byts chunk header, 11bytes msg heder
        (char)0x02,
        (char)0x00, (char)0x00, (char)0x00, // timestamp
        (char)0x00, (char)0x01, (char)0x10, // length, 272
        (char)0x09, // message_type
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, // stream_id
        // msg payload start
        (char)0x02, (char)0x00, (char)0x07, (char)0x63,
        (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
        (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
        (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
        (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
        (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
        (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
        (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
        (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c,
        // chunk #2
        (char)0xC2, /*next chunk.*/ (char)0x61, (char)0x79, (char)0x65, (char)0x72,
        (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
        (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
        (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
        (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
        (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
        (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        // chunk #2
        (char)0xC2, /*next chunk.*/
        (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
    };
    bio.in_buffer.append(data, sizeof(data));

    SrsCommonMessage* msg = NULL;
    ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
    SrsAutoFree(SrsCommonMessage, msg);
    EXPECT_TRUE(msg->header.is_video());
    // 1B cid(6bits), min is 2
    EXPECT_EQ(0x02, msg->header.perfer_cid);
}

/**
* a video message, in 2 chunks packet.
* use 1B chunk header, cid in 2-63
*/
TEST(ProtocolStackTest, ProtocolRecvVCid1BNormal) {
    MockBufferIO bio;
    SrsProtocol proto(&bio);

    // video message
    char data[] = {
        // 12bytes header, 1byts chunk header, 11bytes msg heder
        (char)0x09,
        (char)0x00, (char)0x00, (char)0x00, // timestamp
        (char)0x00, (char)0x01, (char)0x10, // length, 272
        (char)0x09, // message_type
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, // stream_id
        // msg payload start
        (char)0x02, (char)0x00, (char)0x07, (char)0x63,
        (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
        (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
        (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
        (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
        (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
        (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
        (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
        (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c,
        // chunk #2
        (char)0xC9, /*next chunk.*/ (char)0x61, (char)0x79, (char)0x65, (char)0x72,
        (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
        (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
        (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
        (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
        (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
        (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        // chunk #2
        (char)0xC9, /*next chunk.*/
        (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
    };
    bio.in_buffer.append(data, sizeof(data));

    SrsCommonMessage* msg = NULL;
    ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
    SrsAutoFree(SrsCommonMessage, msg);
    EXPECT_TRUE(msg->header.is_video());
    // 1B cid(6bits), cid in 2-63
    EXPECT_EQ(0x09, msg->header.perfer_cid);
}

/**
* a video message, in 2 chunks packet.
* use 1B chunk header, max chunk id is 63.
*/
TEST(ProtocolStackTest, ProtocolRecvVCid1BMax) {
    MockBufferIO bio;
    SrsProtocol proto(&bio);

    // video message
    char data[] = {
        // 12bytes header, 1byts chunk header, 11bytes msg heder
        (char)0x3F,
        (char)0x00, (char)0x00, (char)0x00, // timestamp
        (char)0x00, (char)0x01, (char)0x10, // length, 272
        (char)0x09, // message_type
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, // stream_id
        // msg payload start
        (char)0x02, (char)0x00, (char)0x07, (char)0x63,
        (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
        (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
        (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
        (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
        (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
        (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
        (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
        (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c,
        // chunk #2
        (char)0xFF, /*next chunk.*/ (char)0x61, (char)0x79, (char)0x65, (char)0x72,
        (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
        (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
        (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
        (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
        (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
        (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        // chunk #2
        (char)0xFF, /*next chunk.*/
        (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
    };
    bio.in_buffer.append(data, sizeof(data));

    SrsCommonMessage* msg = NULL;
    ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
    SrsAutoFree(SrsCommonMessage, msg);
    EXPECT_TRUE(msg->header.is_video());
    // 1B cid(6bits), max is 63
    EXPECT_EQ(0x3F, msg->header.perfer_cid);
}

/**
* a video message, in 2 chunks packet.
* use 2B chunk header, min chunk id is 64.
*/
TEST(ProtocolStackTest, ProtocolRecvVCid2BMin) {
    MockBufferIO bio;
    SrsProtocol proto(&bio);

    // video message
    char data[] = {
        // 12bytes header, 1byts chunk header, 11bytes msg heder
        (char)0x00, (char)0x00,
        (char)0x00, (char)0x00, (char)0x00, // timestamp
        (char)0x00, (char)0x01, (char)0x10, // length, 272
        (char)0x09, // message_type
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, // stream_id
        // msg payload start
        (char)0x02, (char)0x00, (char)0x07, (char)0x63,
        (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
        (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
        (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
        (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
        (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
        (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
        (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
        (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c,
        // chunk #2
        (char)0xC0, (char)0x00, /*next chunk.*/ (char)0x61, (char)0x79, (char)0x65, (char)0x72,
        (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
        (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
        (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
        (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
        (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
        (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        // chunk #2
        (char)0xC0, (char)0x00, /*next chunk.*/
        (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
    };
    bio.in_buffer.append(data, sizeof(data));

    SrsCommonMessage* msg = NULL;
    ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
    SrsAutoFree(SrsCommonMessage, msg);
    EXPECT_TRUE(msg->header.is_video());
    // 2B cid(8bits), min is 64
    EXPECT_EQ(64, msg->header.perfer_cid);
}

/**
* a video message, in 2 chunks packet.
* use 2B chunk header, cid in 64-319
*/
TEST(ProtocolStackTest, ProtocolRecvVCid2BNormal) {
    MockBufferIO bio;
    SrsProtocol proto(&bio);

    // video message
    char data[] = {
        // 12bytes header, 1byts chunk header, 11bytes msg heder
        (char)0x00, (char)0x10,
        (char)0x00, (char)0x00, (char)0x00, // timestamp
        (char)0x00, (char)0x01, (char)0x10, // length, 272
        (char)0x09, // message_type
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, // stream_id
        // msg payload start
        (char)0x02, (char)0x00, (char)0x07, (char)0x63,
        (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
        (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
        (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
        (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
        (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
        (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
        (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
        (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c,
        // chunk #2
        (char)0xC0, (char)0x10, /*next chunk.*/ (char)0x61, (char)0x79, (char)0x65, (char)0x72,
        (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
        (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
        (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
        (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
        (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
        (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        // chunk #2
        (char)0xC0, (char)0x10, /*next chunk.*/
        (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
    };
    bio.in_buffer.append(data, sizeof(data));

    SrsCommonMessage* msg = NULL;
    ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
    SrsAutoFree(SrsCommonMessage, msg);
    EXPECT_TRUE(msg->header.is_video());
    // 2B cid(8bits), cid in 64-319
    EXPECT_EQ(0x10 + 64, msg->header.perfer_cid);
}

/**
* a video message, in 2 chunks packet.
* use 2B chunk header, cid in 64-319
*/
TEST(ProtocolStackTest, ProtocolRecvVCid2BNormal2) {
    MockBufferIO bio;
    SrsProtocol proto(&bio);

    // video message
    char data[] = {
        // 12bytes header, 1byts chunk header, 11bytes msg heder
        (char)0x00, (char)0x11,
        (char)0x00, (char)0x00, (char)0x00, // timestamp
        (char)0x00, (char)0x01, (char)0x10, // length, 272
        (char)0x09, // message_type
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, // stream_id
        // msg payload start
        (char)0x02, (char)0x00, (char)0x07, (char)0x63,
        (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
        (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
        (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
        (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
        (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
        (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
        (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
        (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c,
        // chunk #2
        (char)0xC0, (char)0x11, /*next chunk.*/ (char)0x61, (char)0x79, (char)0x65, (char)0x72,
        (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
        (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
        (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
        (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
        (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
        (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        // chunk #2
        (char)0xC0, (char)0x11, /*next chunk.*/
        (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
    };
    bio.in_buffer.append(data, sizeof(data));

    SrsCommonMessage* msg = NULL;
    ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
    SrsAutoFree(SrsCommonMessage, msg);
    EXPECT_TRUE(msg->header.is_video());
    // 2B cid(8bits), cid in 64-319
    EXPECT_EQ(0x11 + 64, msg->header.perfer_cid);
}

/**
* a video message, in 2 chunks packet.
* use 2B chunk header, max chunk id is 319.
*/
TEST(ProtocolStackTest, ProtocolRecvVCid2BMax) {
    MockBufferIO bio;
    SrsProtocol proto(&bio);

    // video message
    char data[] = {
        // 12bytes header, 1byts chunk header, 11bytes msg heder
        (char)0x00, (char)0xFF,
        (char)0x00, (char)0x00, (char)0x00, // timestamp
        (char)0x00, (char)0x01, (char)0x10, // length, 272
        (char)0x09, // message_type
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, // stream_id
        // msg payload start
        (char)0x02, (char)0x00, (char)0x07, (char)0x63,
        (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
        (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
        (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
        (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
        (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
        (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
        (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
        (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c,
        // chunk #2
        (char)0xC0, (char)0xFF, /*next chunk.*/ (char)0x61, (char)0x79, (char)0x65, (char)0x72,
        (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
        (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
        (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
        (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
        (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
        (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        // chunk #2
        (char)0xC0, (char)0xFF, /*next chunk.*/
        (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
    };
    bio.in_buffer.append(data, sizeof(data));

    SrsCommonMessage* msg = NULL;
    ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
    SrsAutoFree(SrsCommonMessage, msg);
    EXPECT_TRUE(msg->header.is_video());
    // 2B cid(68bits), max is 319
    EXPECT_EQ(319, msg->header.perfer_cid);
}

/**
* a video message, in 2 chunks packet.
* use 3B chunk header, min chunk id is 64.
*/
TEST(ProtocolStackTest, ProtocolRecvVCid3BMin) {
    MockBufferIO bio;
    SrsProtocol proto(&bio);

    // video message
    char data[] = {
        // 12bytes header, 1byts chunk header, 11bytes msg heder
        (char)0x01, (char)0x00, (char)0x00,
        (char)0x00, (char)0x00, (char)0x00, // timestamp
        (char)0x00, (char)0x01, (char)0x10, // length, 272
        (char)0x09, // message_type
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, // stream_id
        // msg payload start
        (char)0x02, (char)0x00, (char)0x07, (char)0x63,
        (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
        (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
        (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
        (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
        (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
        (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
        (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
        (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c,
        // chunk #2
        (char)0xC1, (char)0x00, (char)0x00, /*next chunk.*/ (char)0x61, (char)0x79, (char)0x65, (char)0x72,
        (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
        (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
        (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
        (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
        (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
        (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        // chunk #2
        (char)0xC1, (char)0x00, (char)0x00, /*next chunk.*/
        (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
    };
    bio.in_buffer.append(data, sizeof(data));

    SrsCommonMessage* msg = NULL;
    ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
    SrsAutoFree(SrsCommonMessage, msg);
    EXPECT_TRUE(msg->header.is_video());
    // 3B cid(16bits), min is 64
    EXPECT_EQ(64, msg->header.perfer_cid);
}

/**
* a video message, in 2 chunks packet.
* use 3B chunk header, cid in 64-65599
*/
TEST(ProtocolStackTest, ProtocolRecvVCid3BNormal) {
    MockBufferIO bio;
    SrsProtocol proto(&bio);

    // video message
    char data[] = {
        // 12bytes header, 1byts chunk header, 11bytes msg heder
        (char)0x01, (char)0x00, (char)0x10,
        (char)0x00, (char)0x00, (char)0x00, // timestamp
        (char)0x00, (char)0x01, (char)0x10, // length, 272
        (char)0x09, // message_type
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, // stream_id
        // msg payload start
        (char)0x02, (char)0x00, (char)0x07, (char)0x63,
        (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
        (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
        (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
        (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
        (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
        (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
        (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
        (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c,
        // chunk #2
        (char)0xC1, (char)0x00, (char)0x10, /*next chunk.*/ (char)0x61, (char)0x79, (char)0x65, (char)0x72,
        (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
        (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
        (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
        (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
        (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
        (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        // chunk #2
        (char)0xC1, (char)0x00, (char)0x10, /*next chunk.*/
        (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
    };
    bio.in_buffer.append(data, sizeof(data));

    SrsCommonMessage* msg = NULL;
    ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
    SrsAutoFree(SrsCommonMessage, msg);
    EXPECT_TRUE(msg->header.is_video());
    // 3B cid(16bits), cid in 64-65599
    EXPECT_EQ(0x10 * 256 + 64, msg->header.perfer_cid);
}

/**
* a video message, in 2 chunks packet.
* use 3B chunk header, cid in 64-65599, greater than 319
*/
TEST(ProtocolStackTest, ProtocolRecvVCid3BNormal2) {
    MockBufferIO bio;
    SrsProtocol proto(&bio);

    // video message
    char data[] = {
        // 12bytes header, 1byts chunk header, 11bytes msg heder
        (char)0x01, (char)0x01, (char)0x10,
        (char)0x00, (char)0x00, (char)0x00, // timestamp
        (char)0x00, (char)0x01, (char)0x10, // length, 272
        (char)0x09, // message_type
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, // stream_id
        // msg payload start
        (char)0x02, (char)0x00, (char)0x07, (char)0x63,
        (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
        (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
        (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
        (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
        (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
        (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
        (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
        (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c,
        // chunk #2
        (char)0xC1, (char)0x01, (char)0x10, /*next chunk.*/ (char)0x61, (char)0x79, (char)0x65, (char)0x72,
        (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
        (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
        (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
        (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
        (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
        (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        // chunk #2
        (char)0xC1, (char)0x01, (char)0x10, /*next chunk.*/
        (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
    };
    bio.in_buffer.append(data, sizeof(data));

    SrsCommonMessage* msg = NULL;
    ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
    SrsAutoFree(SrsCommonMessage, msg);
    EXPECT_TRUE(msg->header.is_video());
    // 3B cid(16bits), cid in 64-65599
    EXPECT_EQ(0x01 + (0x10 * 256) + 64, msg->header.perfer_cid);
}

/**
* a video message, in 2 chunks packet.
* use 3B chunk header, cid in 64-65599, greater than 319
*/
TEST(ProtocolStackTest, ProtocolRecvVCid3BNormal3) {
    MockBufferIO bio;
    SrsProtocol proto(&bio);

    // video message
    char data[] = {
        // 12bytes header, 1byts chunk header, 11bytes msg heder
        (char)0x01, (char)0xFF, (char)0x10,
        (char)0x00, (char)0x00, (char)0x00, // timestamp
        (char)0x00, (char)0x01, (char)0x10, // length, 272
        (char)0x09, // message_type
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, // stream_id
        // msg payload start
        (char)0x02, (char)0x00, (char)0x07, (char)0x63,
        (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
        (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
        (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
        (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
        (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
        (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
        (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
        (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c,
        // chunk #2
        (char)0xC1, (char)0xFF, (char)0x10, /*next chunk.*/ (char)0x61, (char)0x79, (char)0x65, (char)0x72,
        (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
        (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
        (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
        (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
        (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
        (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        // chunk #2
        (char)0xC1, (char)0xFF, (char)0x10, /*next chunk.*/
        (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
    };
    bio.in_buffer.append(data, sizeof(data));

    SrsCommonMessage* msg = NULL;
    ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
    SrsAutoFree(SrsCommonMessage, msg);
    EXPECT_TRUE(msg->header.is_video());
    // 3B cid(16bits), cid in 64-65599
    EXPECT_EQ(0xFF + (0x10 * 256) + 64, msg->header.perfer_cid);
}

/**
* a video message, in 2 chunks packet.
* use 3B chunk header, cid in 64-65599, greater than 319
*/
TEST(ProtocolStackTest, ProtocolRecvVCid3BNormal4) {
    MockBufferIO bio;
    SrsProtocol proto(&bio);

    // video message
    char data[] = {
        // 12bytes header, 1byts chunk header, 11bytes msg heder
        (char)0x01, (char)0x02, (char)0x10,
        (char)0x00, (char)0x00, (char)0x00, // timestamp
        (char)0x00, (char)0x01, (char)0x10, // length, 272
        (char)0x09, // message_type
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, // stream_id
        // msg payload start
        (char)0x02, (char)0x00, (char)0x07, (char)0x63,
        (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
        (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
        (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
        (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
        (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
        (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
        (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
        (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c,
        // chunk #2
        (char)0xC1, (char)0x02, (char)0x10, /*next chunk.*/ (char)0x61, (char)0x79, (char)0x65, (char)0x72,
        (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
        (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
        (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
        (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
        (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
        (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        // chunk #2
        (char)0xC1, (char)0x02, (char)0x10, /*next chunk.*/
        (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
    };
    bio.in_buffer.append(data, sizeof(data));

    SrsCommonMessage* msg = NULL;
    ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
    SrsAutoFree(SrsCommonMessage, msg);
    EXPECT_TRUE(msg->header.is_video());
    // 3B cid(16bits), cid in 64-65599
    EXPECT_EQ(0x02 + (0x10 * 256) + 64, msg->header.perfer_cid);
}

/**
* a video message, in 2 chunks packet.
* use 3B chunk header, max chunk id is 65599.
*/
TEST(ProtocolStackTest, ProtocolRecvVCid3BMax) {
    MockBufferIO bio;
    SrsProtocol proto(&bio);

    // video message
    char data[] = {
        // 12bytes header, 1byts chunk header, 11bytes msg heder
        (char)0x01, (char)0xFF, (char)0xFF,
        (char)0x00, (char)0x00, (char)0x00, // timestamp
        (char)0x00, (char)0x01, (char)0x10, // length, 272
        (char)0x09, // message_type
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, // stream_id
        // msg payload start
        (char)0x02, (char)0x00, (char)0x07, (char)0x63,
        (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
        (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
        (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
        (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
        (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
        (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
        (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
        (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c,
        // chunk #2
        (char)0xC1, (char)0xFF, (char)0xFF, /*next chunk.*/ (char)0x61, (char)0x79, (char)0x65, (char)0x72,
        (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
        (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
        (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
        (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
        (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
        (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        // chunk #2
        (char)0xC1, (char)0xFF, (char)0xFF, /*next chunk.*/
        (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
    };
    bio.in_buffer.append(data, sizeof(data));

    SrsCommonMessage* msg = NULL;
    ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
    SrsAutoFree(SrsCommonMessage, msg);
    EXPECT_TRUE(msg->header.is_video());
    // 2B cid(16bits), max is 65599
    EXPECT_EQ(65599, msg->header.perfer_cid);
}

/**
* recv a zero length video message.
*/
TEST(ProtocolStackTest, ProtocolRecvV0LenMessage) {
    MockBufferIO bio;
    SrsProtocol proto(&bio);

    // video message
    char data[] = {
        // video #1
        // 12bytes header, 1byts chunk header, 11bytes msg heder
        (char)0x03,
        (char)0x00, (char)0x00, (char)0x00, // timestamp
        (char)0x00, (char)0x00, (char)0x00, // length
        (char)0x09, // message_type
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, // stream_id

        // video #2
        // 12bytes header, 1byts chunk header, 11bytes msg heder
        (char)0x03,
        (char)0x00, (char)0x00, (char)0x00, // timestamp
        (char)0x00, (char)0x00, (char)0x04, // length
        (char)0x09, // message_type
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, // stream_id
        // msg payload start
        (char)0x00, (char)0x00, (char)0x07, (char)0x63
    };
    bio.in_buffer.append(data, sizeof(data));

    SrsCommonMessage* msg = NULL;
    ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
    SrsAutoFree(SrsCommonMessage, msg);
    EXPECT_TRUE(msg->header.is_video());
    // protocol stack will ignore the empty video message.
    EXPECT_EQ(4, msg->header.payload_length);
}

/**
* send a video message
*/
TEST(ProtocolStackTest, ProtocolSendVMessage) {
    MockBufferIO bio;
    SrsProtocol proto(&bio);

    char data[] = {0x01, 0x02, 0x03, 0x04};

    SrsCommonMessage* msg = new SrsCommonMessage();
    msg->size = sizeof(data);
    msg->payload = new char[msg->size];
    memcpy(msg->payload, data, msg->size);

    SrsSharedPtrMessage m;
    ASSERT_TRUE(ERROR_SUCCESS == m.create(msg));

    EXPECT_TRUE(ERROR_SUCCESS == proto.send_and_free_message(m.copy(), 0));
    EXPECT_EQ(16, bio.out_buffer.length());
}

/**
* send a SrsCallPacket packet
*/
TEST(ProtocolStackTest, ProtocolSendSrsCallPacket) {
    MockBufferIO bio;
    SrsProtocol proto(&bio);

    SrsAmf0Object* args = SrsAmf0Any::object();

    SrsCallPacket* pkt = new SrsCallPacket();
    pkt->command_name = "my_call";
    pkt->command_object = SrsAmf0Any::null();
    pkt->arguments = args;

    args->set("video_id", SrsAmf0Any::number(100));
    args->set("url", SrsAmf0Any::str("http://ossrs.net/api/v1/videos/100"));
    args->set("date", SrsAmf0Any::str("2014-07-11 16:20:10.2984"));

    EXPECT_TRUE(ERROR_SUCCESS == proto.send_and_free_packet(pkt, 0));
    char buf[] = {
        (char)0x03, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x76, (char)0x14,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x02, (char)0x00, (char)0x07, (char)0x6d,
        (char)0x79, (char)0x5f, (char)0x63, (char)0x61, (char)0x6c, (char)0x6c, (char)0x00, (char)0x00,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x05,
        (char)0x03, (char)0x00, (char)0x08, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f,
        (char)0x5f, (char)0x69, (char)0x64, (char)0x00, (char)0x40, (char)0x59, (char)0x00, (char)0x00,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03, (char)0x75, (char)0x72,
        (char)0x6c, (char)0x02, (char)0x00, (char)0x22, (char)0x68, (char)0x74, (char)0x74, (char)0x70,
        (char)0x3a, (char)0x2f, (char)0x2f, (char)0x6f, (char)0x73, (char)0x73, (char)0x72, (char)0x73,
        (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x2f, (char)0x61, (char)0x70, (char)0x69,
        (char)0x2f, (char)0x76, (char)0x31, (char)0x2f, (char)0x76, (char)0x69, (char)0x64, (char)0x65,
        (char)0x6f, (char)0x73, (char)0x2f, (char)0x31, (char)0x30, (char)0x30, (char)0x00, (char)0x04,
        (char)0x64, (char)0x61, (char)0x74, (char)0x65, (char)0x02, (char)0x00, (char)0x18, (char)0x32,
        (char)0x30, (char)0x31, (char)0x34, (char)0x2d, (char)0x30, (char)0x37, (char)0x2d, (char)0x31,
        (char)0x31, (char)0x20, (char)0x31, (char)0x36, (char)0x3a, (char)0x32, (char)0x30, (char)0x3a,
        (char)0x31, (char)0x30, (char)0x2e, (char)0x32, (char)0x39, (char)0x38, (char)0x34, (char)0x00,
        (char)0x00, (char)0x09
    };
    EXPECT_TRUE(srs_bytes_equals(bio.out_buffer.bytes(), buf, sizeof(buf)));
}

/**
* send a SrsCallResPacket packet
*/
TEST(ProtocolStackTest, ProtocolSendSrsCallResPacket) {
    MockBufferIO bio;
    SrsProtocol proto(&bio);

    SrsAmf0Object* args = SrsAmf0Any::object();

    SrsCallResPacket* pkt = new SrsCallResPacket(0);
    pkt->command_name = "_result";
    pkt->command_object = SrsAmf0Any::null();
    pkt->response = args;

    args->set("video_id", SrsAmf0Any::number(100));
    args->set("url", SrsAmf0Any::str("http://ossrs.net/api/v1/videos/100"));
    args->set("date", SrsAmf0Any::str("2014-07-11 16:20:10.2984"));

    EXPECT_TRUE(ERROR_SUCCESS == proto.send_and_free_packet(pkt, 0));
    char buf[] = {
        (char)0x03, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x76, (char)0x14,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x02, (char)0x00, (char)0x07, (char)0x5f,
        (char)0x72, (char)0x65, (char)0x73, (char)0x75, (char)0x6c, (char)0x74, (char)0x00, (char)0x00,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x05,
        (char)0x03, (char)0x00, (char)0x08, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f,
        (char)0x5f, (char)0x69, (char)0x64, (char)0x00, (char)0x40, (char)0x59, (char)0x00, (char)0x00,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03, (char)0x75, (char)0x72,
        (char)0x6c, (char)0x02, (char)0x00, (char)0x22, (char)0x68, (char)0x74, (char)0x74, (char)0x70,
        (char)0x3a, (char)0x2f, (char)0x2f, (char)0x6f, (char)0x73, (char)0x73, (char)0x72, (char)0x73,
        (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x2f, (char)0x61, (char)0x70, (char)0x69,
        (char)0x2f, (char)0x76, (char)0x31, (char)0x2f, (char)0x76, (char)0x69, (char)0x64, (char)0x65,
        (char)0x6f, (char)0x73, (char)0x2f, (char)0x31, (char)0x30, (char)0x30, (char)0x00, (char)0x04,
        (char)0x64, (char)0x61, (char)0x74, (char)0x65, (char)0x02, (char)0x00, (char)0x18, (char)0x32,
        (char)0x30, (char)0x31, (char)0x34, (char)0x2d, (char)0x30, (char)0x37, (char)0x2d, (char)0x31,
        (char)0x31, (char)0x20, (char)0x31, (char)0x36, (char)0x3a, (char)0x32, (char)0x30, (char)0x3a,
        (char)0x31, (char)0x30, (char)0x2e, (char)0x32, (char)0x39, (char)0x38, (char)0x34, (char)0x00,
        (char)0x00, (char)0x09
    };
    EXPECT_TRUE(srs_bytes_equals(bio.out_buffer.bytes(), buf, sizeof(buf)));
}

/**
* send a SrsCreateStreamPacket packet
*/
TEST(ProtocolStackTest, ProtocolSendSrsCreateStreamPacket) {
    MockBufferIO bio;
    SrsProtocol proto(&bio);

    SrsCreateStreamPacket* pkt = new SrsCreateStreamPacket();
    pkt->command_object = SrsAmf0Any::null();

    EXPECT_TRUE(ERROR_SUCCESS == proto.send_and_free_packet(pkt, 0));
    char buf[] = {
        (char)0x03, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x19, (char)0x14,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x02, (char)0x00, (char)0x0c, (char)0x63,
        (char)0x72, (char)0x65, (char)0x61, (char)0x74, (char)0x65, (char)0x53, (char)0x74, (char)0x72,
        (char)0x65, (char)0x61, (char)0x6d, (char)0x00, (char)0x40, (char)0x00, (char)0x00, (char)0x00,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x05
    };
    EXPECT_TRUE(srs_bytes_equals(bio.out_buffer.bytes(), buf, sizeof(buf)));
}

/**
* send a SrsFMLEStartPacket packet
*/
TEST(ProtocolStackTest, ProtocolSendSrsFMLEStartPacket) {
    MockBufferIO bio;
    SrsProtocol proto(&bio);

    SrsFMLEStartPacket* pkt = new SrsFMLEStartPacket();
    pkt->command_name = "FMLEStart";
    pkt->command_object = SrsAmf0Any::null();
    pkt->stream_name = "livestream";

    EXPECT_TRUE(ERROR_SUCCESS == proto.send_and_free_packet(pkt, 0));
    char buf[] = {
        (char)0x03, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x23, (char)0x14,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x02, (char)0x00, (char)0x09, (char)0x46,
        (char)0x4d, (char)0x4c, (char)0x45, (char)0x53, (char)0x74, (char)0x61, (char)0x72, (char)0x74,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        (char)0x00, (char)0x05, (char)0x02, (char)0x00, (char)0x0a, (char)0x6c, (char)0x69, (char)0x76,
        (char)0x65, (char)0x73, (char)0x74, (char)0x72, (char)0x65, (char)0x61, (char)0x6d
    };
    EXPECT_TRUE(srs_bytes_equals(bio.out_buffer.bytes(), buf, sizeof(buf)));
}

/**
* send a SrsFMLEStartResPacket packet
*/
TEST(ProtocolStackTest, ProtocolSendSrsFMLEStartResPacket) {
    MockBufferIO bio;
    SrsProtocol proto(&bio);

    SrsAmf0Object* args = SrsAmf0Any::object();

    SrsFMLEStartResPacket* pkt = new SrsFMLEStartResPacket(1);
    pkt->command_name = "FMLEStart";
    pkt->command_object = SrsAmf0Any::null();
    pkt->args = args;

    args->set("stream", SrsAmf0Any::str("livestream"));
    args->set("start", SrsAmf0Any::number(0));

    EXPECT_TRUE(ERROR_SUCCESS == proto.send_and_free_packet(pkt, 0));
    char buf[] = {
        (char)0x03, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x17, (char)0x14,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x02, (char)0x00, (char)0x09, (char)0x46,
        (char)0x4d, (char)0x4c, (char)0x45, (char)0x53, (char)0x74, (char)0x61, (char)0x72, (char)0x74,
        (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        (char)0x00, (char)0x05, (char)0x06
    };
    EXPECT_TRUE(srs_bytes_equals(bio.out_buffer.bytes(), buf, sizeof(buf)));
}

/**
* send a SrsPublishPacket packet
*/
TEST(ProtocolStackTest, ProtocolSendSrsPublishPacket) {
    MockBufferIO bio;
    SrsProtocol proto(&bio);

    SrsPublishPacket* pkt = new SrsPublishPacket();
    pkt->command_name = "publish";
    pkt->command_object = SrsAmf0Any::null();
    pkt->stream_name = "livestream";
    pkt->type = "live";

    EXPECT_TRUE(ERROR_SUCCESS == proto.send_and_free_packet(pkt, 0));
    char buf[] = {
        (char)0x05, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x28, (char)0x14,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x02, (char)0x00, (char)0x07, (char)0x70,
        (char)0x75, (char)0x62, (char)0x6c, (char)0x69, (char)0x73, (char)0x68, (char)0x00, (char)0x00,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x05,
        (char)0x02, (char)0x00, (char)0x0a, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x73,
        (char)0x74, (char)0x72, (char)0x65, (char)0x61, (char)0x6d, (char)0x02, (char)0x00, (char)0x04,
        (char)0x6c, (char)0x69, (char)0x76, (char)0x65
    };
    EXPECT_TRUE(srs_bytes_equals(bio.out_buffer.bytes(), buf, sizeof(buf)));
}

/**
* send a SrsPlayResPacket packet
*/
TEST(ProtocolStackTest, ProtocolSendSrsPlayResPacket) {
    MockBufferIO bio;
    SrsProtocol proto(&bio);

    SrsAmf0Object* args = SrsAmf0Any::object();

    SrsPlayResPacket* pkt = new SrsPlayResPacket();
    pkt->command_name = "_result";
    pkt->command_object = SrsAmf0Any::null();
    pkt->desc = args;

    args->set("stream", SrsAmf0Any::str("livestream"));
    args->set("start", SrsAmf0Any::number(0));

    EXPECT_TRUE(ERROR_SUCCESS == proto.send_and_free_packet(pkt, 0));
    char buf[] = {
        (char)0x05, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x3d, (char)0x14,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x02, (char)0x00, (char)0x07, (char)0x5f,
        (char)0x72, (char)0x65, (char)0x73, (char)0x75, (char)0x6c, (char)0x74, (char)0x00, (char)0x00,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x05,
        (char)0x03, (char)0x00, (char)0x06, (char)0x73, (char)0x74, (char)0x72, (char)0x65, (char)0x61,
        (char)0x6d, (char)0x02, (char)0x00, (char)0x0a, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
        (char)0x73, (char)0x74, (char)0x72, (char)0x65, (char)0x61, (char)0x6d, (char)0x00, (char)0x05,
        (char)0x73, (char)0x74, (char)0x61, (char)0x72, (char)0x74, (char)0x00, (char)0x00, (char)0x00,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        (char)0x09
    };
    EXPECT_TRUE(srs_bytes_equals(bio.out_buffer.bytes(), buf, sizeof(buf)));
}

/**
* send a SrsOnBWDonePacket packet
*/
TEST(ProtocolStackTest, ProtocolSendSrsOnBWDonePacket) {
    MockBufferIO bio;
    SrsProtocol proto(&bio);

    SrsOnBWDonePacket* pkt = new SrsOnBWDonePacket();
    pkt->command_name = "onBWDone";
    pkt->args = SrsAmf0Any::null();

    EXPECT_TRUE(ERROR_SUCCESS == proto.send_and_free_packet(pkt, 0));
    char buf[] = {
        (char)0x03, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x15, (char)0x14,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x02, (char)0x00, (char)0x08, (char)0x6f,
        (char)0x6e, (char)0x42, (char)0x57, (char)0x44, (char)0x6f, (char)0x6e, (char)0x65, (char)0x00,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        (char)0x05
    };
    EXPECT_TRUE(srs_bytes_equals(bio.out_buffer.bytes(), buf, sizeof(buf)));
}

/**
* send a SrsOnStatusCallPacket packet
*/
TEST(ProtocolStackTest, ProtocolSendSrsOnStatusCallPacket) {
    MockBufferIO bio;
    SrsProtocol proto(&bio);

    SrsAmf0Object* args = SrsAmf0Any::object();

    args->set("stream", SrsAmf0Any::str("livestream"));
    args->set("start", SrsAmf0Any::number(0));

    SrsOnStatusCallPacket* pkt = new SrsOnStatusCallPacket();
    pkt->command_name = "onStatus";
    pkt->args = SrsAmf0Any::null();
    pkt->data = args;

    EXPECT_TRUE(ERROR_SUCCESS == proto.send_and_free_packet(pkt, 0));
    char buf[] = {
        (char)0x05, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x3e, (char)0x14,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x02, (char)0x00, (char)0x08, (char)0x6f,
        (char)0x6e, (char)0x53, (char)0x74, (char)0x61, (char)0x74, (char)0x75, (char)0x73, (char)0x00,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        (char)0x05, (char)0x03, (char)0x00, (char)0x06, (char)0x73, (char)0x74, (char)0x72, (char)0x65,
        (char)0x61, (char)0x6d, (char)0x02, (char)0x00, (char)0x0a, (char)0x6c, (char)0x69, (char)0x76,
        (char)0x65, (char)0x73, (char)0x74, (char)0x72, (char)0x65, (char)0x61, (char)0x6d, (char)0x00,
        (char)0x05, (char)0x73, (char)0x74, (char)0x61, (char)0x72, (char)0x74, (char)0x00, (char)0x00,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        (char)0x00, (char)0x09
    };
    EXPECT_TRUE(srs_bytes_equals(bio.out_buffer.bytes(), buf, sizeof(buf)));
}

/**
* send a SrsBandwidthPacket packet
*/
TEST(ProtocolStackTest, ProtocolSendSrsBandwidthPacket) {
    MockBufferIO bio;
    SrsProtocol proto(&bio);

    SrsAmf0Object* args = SrsAmf0Any::object();

    args->set("stream", SrsAmf0Any::str("livestream"));
    args->set("start", SrsAmf0Any::number(0));

    SrsBandwidthPacket* pkt = new SrsBandwidthPacket();
    pkt->command_name = "startPublish";
    pkt->args = SrsAmf0Any::null();
    pkt->data = args;

    EXPECT_TRUE(ERROR_SUCCESS == proto.send_and_free_packet(pkt, 0));
    char buf[] = {
        (char)0x05, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x42, (char)0x14,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x02, (char)0x00, (char)0x0c, (char)0x73,
        (char)0x74, (char)0x61, (char)0x72, (char)0x74, (char)0x50, (char)0x75, (char)0x62, (char)0x6c,
        (char)0x69, (char)0x73, (char)0x68, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x05, (char)0x03, (char)0x00, (char)0x06,
        (char)0x73, (char)0x74, (char)0x72, (char)0x65, (char)0x61, (char)0x6d, (char)0x02, (char)0x00,
        (char)0x0a, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x73, (char)0x74, (char)0x72,
        (char)0x65, (char)0x61, (char)0x6d, (char)0x00, (char)0x05, (char)0x73, (char)0x74, (char)0x61,
        (char)0x72, (char)0x74, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x09
    };
    EXPECT_TRUE(srs_bytes_equals(bio.out_buffer.bytes(), buf, sizeof(buf)));
}

/**
* send a SrsOnStatusDataPacket packet
*/
TEST(ProtocolStackTest, ProtocolSendSrsOnStatusDataPacket) {
    MockBufferIO bio;
    SrsProtocol proto(&bio);

    SrsAmf0Object* args = SrsAmf0Any::object();

    args->set("stream", SrsAmf0Any::str("livestream"));
    args->set("start", SrsAmf0Any::number(0));

    SrsOnStatusDataPacket* pkt = new SrsOnStatusDataPacket();
    pkt->command_name = "onData";
    pkt->data = args;

    EXPECT_TRUE(ERROR_SUCCESS == proto.send_and_free_packet(pkt, 0));
    char buf[] = {
        (char)0x05, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x32, (char)0x12,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x02, (char)0x00, (char)0x06, (char)0x6f,
        (char)0x6e, (char)0x44, (char)0x61, (char)0x74, (char)0x61, (char)0x03, (char)0x00, (char)0x06,
        (char)0x73, (char)0x74, (char)0x72, (char)0x65, (char)0x61, (char)0x6d, (char)0x02, (char)0x00,
        (char)0x0a, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x73, (char)0x74, (char)0x72,
        (char)0x65, (char)0x61, (char)0x6d, (char)0x00, (char)0x05, (char)0x73, (char)0x74, (char)0x61,
        (char)0x72, (char)0x74, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x09
    };
    EXPECT_TRUE(srs_bytes_equals(bio.out_buffer.bytes(), buf, sizeof(buf)));
}

/**
* send a SrsSampleAccessPacket packet
*/
TEST(ProtocolStackTest, ProtocolSendSrsSampleAccessPacket) {
    MockBufferIO bio;
    SrsProtocol proto(&bio);

    SrsSampleAccessPacket* pkt = new SrsSampleAccessPacket();
    pkt->command_name = "|RtmpSampleAccess";
    pkt->video_sample_access = true;
    pkt->audio_sample_access = true;

    EXPECT_TRUE(ERROR_SUCCESS == proto.send_and_free_packet(pkt, 0));
    char buf[] = {
        (char)0x05, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x18, (char)0x12,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x02, (char)0x00, (char)0x11, (char)0x7c,
        (char)0x52, (char)0x74, (char)0x6d, (char)0x70, (char)0x53, (char)0x61, (char)0x6d, (char)0x70,
        (char)0x6c, (char)0x65, (char)0x41, (char)0x63, (char)0x63, (char)0x65, (char)0x73, (char)0x73,
        (char)0x01, (char)0x01, (char)0x01, (char)0x01
    };
    EXPECT_TRUE(srs_bytes_equals(bio.out_buffer.bytes(), buf, sizeof(buf)));
}

/**
* send a SrsOnMetaDataPacket packet
*/
TEST(ProtocolStackTest, ProtocolSendSrsOnMetaDataPacket) {
    MockBufferIO bio;
    SrsProtocol proto(&bio);

    SrsAmf0Object* args = SrsAmf0Any::object();

    args->set("width", SrsAmf0Any::number(1024));
    args->set("height", SrsAmf0Any::number(576));

    SrsOnMetaDataPacket* pkt = new SrsOnMetaDataPacket();
    pkt->name = "onMetaData";
    pkt->metadata = args;

    EXPECT_TRUE(ERROR_SUCCESS == proto.send_and_free_packet(pkt, 0));
    char buf[] = {
        (char)0x04, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x32, (char)0x12,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x02, (char)0x00, (char)0x0a, (char)0x6f,
        (char)0x6e, (char)0x4d, (char)0x65, (char)0x74, (char)0x61, (char)0x44, (char)0x61, (char)0x74,
        (char)0x61, (char)0x03, (char)0x00, (char)0x05, (char)0x77, (char)0x69, (char)0x64, (char)0x74,
        (char)0x68, (char)0x00, (char)0x40, (char)0x90, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        (char)0x00, (char)0x00, (char)0x00, (char)0x06, (char)0x68, (char)0x65, (char)0x69, (char)0x67,
        (char)0x68, (char)0x74, (char)0x00, (char)0x40, (char)0x82, (char)0x00, (char)0x00, (char)0x00,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x09
    };
    EXPECT_TRUE(srs_bytes_equals(bio.out_buffer.bytes(), buf, sizeof(buf)));
}

/**
* send a SrsSetWindowAckSizePacket packet
*/
TEST(ProtocolStackTest, ProtocolSendSrsSetWindowAckSizePacket) {
    MockBufferIO bio;
    SrsProtocol proto(&bio);

    SrsSetWindowAckSizePacket* pkt = new SrsSetWindowAckSizePacket();
    pkt->ackowledgement_window_size = 102400;

    EXPECT_TRUE(ERROR_SUCCESS == proto.send_and_free_packet(pkt, 0));
    char buf[] = {
        (char)0x02, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x04, (char)0x05,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x01, (char)0x90, (char)0x00
    };
    EXPECT_TRUE(srs_bytes_equals(bio.out_buffer.bytes(), buf, sizeof(buf)));
}

/**
* send a SrsAcknowledgementPacket packet
*/
TEST(ProtocolStackTest, ProtocolSendSrsAcknowledgementPacket) {
    MockBufferIO bio;
    SrsProtocol proto(&bio);

    SrsAcknowledgementPacket* pkt = new SrsAcknowledgementPacket();
    pkt->sequence_number = 1024;

    EXPECT_TRUE(ERROR_SUCCESS == proto.send_and_free_packet(pkt, 0));
    char buf[] = {
        (char)0x02, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x04, (char)0x03,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x04, (char)0x00
    };
    EXPECT_TRUE(srs_bytes_equals(bio.out_buffer.bytes(), buf, sizeof(buf)));
}

/**
* send a SrsSetChunkSizePacket packet
*/
TEST(ProtocolStackTest, ProtocolSendSrsSetChunkSizePacket) {
    MockBufferIO bio;
    SrsProtocol proto(&bio);

    SrsSetChunkSizePacket* pkt = new SrsSetChunkSizePacket();
    pkt->chunk_size = 1024;

    EXPECT_TRUE(ERROR_SUCCESS == proto.send_and_free_packet(pkt, 0));
    char buf[] = {
        (char)0x02, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x04, (char)0x01,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x04, (char)0x00
    };
    EXPECT_TRUE(srs_bytes_equals(bio.out_buffer.bytes(), buf, sizeof(buf)));
}

/**
* send a SrsSetPeerBandwidthPacket packet
*/
TEST(ProtocolStackTest, ProtocolSendSrsSetPeerBandwidthPacket) {
    MockBufferIO bio;
    SrsProtocol proto(&bio);

    SrsSetPeerBandwidthPacket* pkt = new SrsSetPeerBandwidthPacket();
    pkt->type = SrsPeerBandwidthSoft;
    pkt->bandwidth = 1024;

    EXPECT_TRUE(ERROR_SUCCESS == proto.send_and_free_packet(pkt, 0));
    char buf[] = {
        (char)0x02, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x05, (char)0x06,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x04, (char)0x00,
        (char)0x01
    };
    EXPECT_TRUE(srs_bytes_equals(bio.out_buffer.bytes(), buf, sizeof(buf)));
}

/**
* send a SrsUserControlPacket packet
*/
TEST(ProtocolStackTest, ProtocolSendSrsUserControlPacket) {
    MockBufferIO bio;
    SrsProtocol proto(&bio);

    SrsUserControlPacket* pkt = new SrsUserControlPacket();
    pkt->event_type = SrcPCUCSetBufferLength;
    pkt->event_data = 0x01;
    pkt->extra_data = 0x10;

    EXPECT_TRUE(ERROR_SUCCESS == proto.send_and_free_packet(pkt, 0));
    char buf[] = {
        (char)0x02, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0a, (char)0x04,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03, (char)0x00, (char)0x00,
        (char)0x00, (char)0x01, (char)0x00, (char)0x00, (char)0x00, (char)0x10
    };

    EXPECT_TRUE(srs_bytes_equals(bio.out_buffer.bytes(), buf, sizeof(buf)));
    EXPECT_TRUE(true);
}

/**
* recv video message from multiple chunks,
* the next chunks must not be fmt=0 which means new msg.
*/
// when exists cache msg, means got an partial message,
// the fmt must not be type0 which means new message.
TEST(ProtocolStackTest, ProtocolRecvVMessageFmtInvalid) {
    MockBufferIO bio;
    SrsProtocol proto(&bio);

    // video message
    char data[] = {
        // 12bytes header, 1byts chunk header, 11bytes msg heder
        (char)0x03,
        (char)0x00, (char)0x00, (char)0x00, // timestamp
        (char)0x00, (char)0x01, (char)0x10, // length, 272
        (char)0x09, // message_type
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, // stream_id
        // msg payload start
        (char)0x02, (char)0x00, (char)0x07, (char)0x63,
        (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
        (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
        (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
        (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
        (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
        (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
        (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
        (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c,
        (char)0x03, /*next chunk.*/ (char)0x61, (char)0x79, (char)0x65, (char)0x72,
        (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
        (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
        (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
        (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
        (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
        (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        (char)0xC3, /*next chunk.*/
        (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
    };
    bio.in_buffer.append(data, sizeof(data));

    SrsCommonMessage* msg = NULL;
    EXPECT_FALSE(ERROR_SUCCESS == proto.recv_message(&msg));
}

/**
* when recv bytes archive the ack-size, server must response a acked-size auto.
*/
TEST(ProtocolStackTest, ProtocolAckSizeFlow) {
    MockBufferIO bio;
    SrsProtocol proto(&bio);

    if (true) {
        SrsSetWindowAckSizePacket* pkt = new SrsSetWindowAckSizePacket();
        pkt->ackowledgement_window_size = 512;

        EXPECT_TRUE(ERROR_SUCCESS == proto.send_and_free_packet(pkt, 0));
    }

    if (true) {
        SrsCommonMessage* msg = new SrsCommonMessage();
        msg->header.payload_length = msg->size = 4096;
        msg->payload = new char[msg->size];

        msg->header.message_type = 9;
        EXPECT_TRUE(msg->header.is_video());

        SrsSharedPtrMessage m;
        ASSERT_TRUE(ERROR_SUCCESS == m.create(msg));

        EXPECT_TRUE(ERROR_SUCCESS == proto.send_and_free_message(m.copy(), 1));
    }

    // copy output to input
    if (true) {
        bio.in_buffer.append(bio.out_buffer.bytes(), bio.out_buffer.length());
        bio.out_buffer.erase(bio.out_buffer.length());
    }

    // recv SrsSetWindowAckSizePacket
    if (true) {
        SrsCommonMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsCommonMessage, msg);
        ASSERT_TRUE(msg->header.is_window_ackledgement_size());
    }
    // recv video
    if (true) {
        SrsCommonMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsCommonMessage, msg);
        ASSERT_TRUE(msg->header.is_video());
    }

    // copy output to input
    if (true) {
        bio.in_buffer.append(bio.out_buffer.bytes(), bio.out_buffer.length());
        bio.out_buffer.erase(bio.out_buffer.length());
    }
    // recv auto send acked size. #1
    if (true) {
        SrsCommonMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsCommonMessage, msg);
        ASSERT_TRUE(msg->header.is_ackledgement());
    }

    // send again
    if (true) {
        SrsCommonMessage* msg = new SrsCommonMessage();
        msg->header.payload_length = msg->size = 4096;
        msg->payload = new char[msg->size];

        msg->header.message_type = 9;
        EXPECT_TRUE(msg->header.is_video());

        SrsSharedPtrMessage m;
        ASSERT_TRUE(ERROR_SUCCESS == m.create(msg));

        EXPECT_TRUE(ERROR_SUCCESS == proto.send_and_free_message(m.copy(), 1));
    }
    // copy output to input
    if (true) {
        bio.in_buffer.append(bio.out_buffer.bytes(), bio.out_buffer.length());
        bio.out_buffer.erase(bio.out_buffer.length());
    }
    // recv video
    if (true) {
        SrsCommonMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsCommonMessage, msg);
        ASSERT_TRUE(msg->header.is_video());
    }

    // copy output to input
    if (true) {
        bio.in_buffer.append(bio.out_buffer.bytes(), bio.out_buffer.length());
        bio.out_buffer.erase(bio.out_buffer.length());
    }
    // recv auto send acked size. #2
    if (true) {
        SrsCommonMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsCommonMessage, msg);
        ASSERT_TRUE(msg->header.is_ackledgement());
    }
}

/**
* when recv ping message, server will response it auto.
*/
TEST(ProtocolStackTest, ProtocolPingFlow) {
    MockBufferIO bio;
    SrsProtocol proto(&bio);

    // ping request
    if (true) {
        SrsUserControlPacket* pkt = new SrsUserControlPacket();
        pkt->event_type = SrcPCUCPingRequest;
        pkt->event_data = 0x3456;
        EXPECT_TRUE(ERROR_SUCCESS == proto.send_and_free_packet(pkt, 0));
    }
    // copy output to input
    if (true) {
        bio.in_buffer.append(bio.out_buffer.bytes(), bio.out_buffer.length());
        bio.out_buffer.erase(bio.out_buffer.length());
    }
    // recv ping
    if (true) {
        SrsCommonMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsCommonMessage, msg);
        EXPECT_TRUE(msg->header.is_user_control_message());
    }

    // recv the server auto send ping response message
    // copy output to input
    if (true) {
        bio.in_buffer.append(bio.out_buffer.bytes(), bio.out_buffer.length());
        bio.out_buffer.erase(bio.out_buffer.length());
    }
    // recv ping
    if (true) {
        SrsCommonMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsCommonMessage, msg);
        ASSERT_TRUE(msg->header.is_user_control_message());

        SrsPacket* pkt = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.decode_message(msg, &pkt));
        SrsUserControlPacket* spkt = dynamic_cast<SrsUserControlPacket*>(pkt);
        ASSERT_TRUE(spkt != NULL);

        EXPECT_TRUE(SrcPCUCPingResponse == spkt->event_type);
        EXPECT_TRUE(0x3456 == spkt->event_data);
    }
}

/**
* expect specified message
*/
TEST(ProtocolStackTest, ProtocolExcpectMessage) {
    MockBufferIO bio;
    SrsProtocol proto(&bio);

    // packet is SrsConnectAppPacket
    char data[] = {
        // 12bytes header, 1byts chunk header, 11bytes msg heder
        (char)0x03, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x01, (char)0xa1, (char)0x14, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        // msg payload start
        (char)0x02, (char)0x00, (char)0x07, (char)0x63,
        (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
        (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
        (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
        (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
        (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
        (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
        (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
        (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c,
        (char)0xC3, /*next chunk.*/ (char)0x61, (char)0x79, (char)0x65, (char)0x72,
        (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
        (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
        (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
        (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
        (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
        (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        (char)0xC3, /*next chunk.*/ (char)0x0d, (char)0x76, (char)0x69, (char)0x64,
        (char)0x65, (char)0x6f, (char)0x46, (char)0x75, (char)0x6e, (char)0x63, (char)0x74, (char)0x69, (char)0x6f, (char)0x6e, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x07, (char)0x70, (char)0x61, (char)0x67, (char)0x65, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x62, (char)0x68,
        (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72, (char)0x73, (char)0x2e,
        (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x73,
        (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2e, (char)0x68, (char)0x74, (char)0x6d, (char)0x6c,
        (char)0x3f, (char)0x76, (char)0x68, (char)0x6f, (char)0x73, (char)0x74, (char)0x3d, (char)0x64, (char)0x65, (char)0x76, (char)0x26, (char)0x73, (char)0x74, (char)0x72, (char)0x65, (char)0x61,
        (char)0x6d, (char)0x3d, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x73, (char)0x74, (char)0x72, (char)0x65, (char)0x61, (char)0x6d, (char)0x26, (char)0x73, (char)0x65, (char)0x72,
        (char)0x76, (char)0x65, (char)0x72, (char)0x3d, (char)0x64, (char)0x65, (char)0x76, (char)0x26, (char)0x70, (char)0x6f, (char)0x72, (char)0x74,
        (char)0xC3, /*next chunk.*/ (char)0x3d, (char)0x31, (char)0x39, (char)0x33,
        (char)0x35, (char)0x00, (char)0x0e, (char)0x6f, (char)0x62, (char)0x6a, (char)0x65, (char)0x63, (char)0x74, (char)0x45, (char)0x6e, (char)0x63, (char)0x6f, (char)0x64, (char)0x69, (char)0x6e,
        (char)0x67, (char)0x00, (char)0x40, (char)0x08, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x09
    };
    bio.in_buffer.append(data, sizeof(data));

    SrsCommonMessage* msg = NULL;
    SrsConnectAppPacket* pkt = NULL;
    ASSERT_TRUE(ERROR_SUCCESS == proto.expect_message<SrsConnectAppPacket>(&msg, &pkt));
    SrsAutoFree(SrsCommonMessage, msg);
    SrsAutoFree(SrsConnectAppPacket, pkt);
    ASSERT_TRUE(NULL != pkt);
}

TEST(ProtocolRTMPTest, RTMPRequest) {
    SrsRequest req;
    std::string param;

    req.stream = "livestream";
    srs_discovery_tc_url("rtmp://std.ossrs.net/live",
                         req.schema, req.host, req.vhost, req.app, req.stream, req.port, param);
    req.strip();
    EXPECT_STREQ("rtmp", req.schema.c_str());
    EXPECT_STREQ("std.ossrs.net", req.host.c_str());
    EXPECT_STREQ("std.ossrs.net", req.vhost.c_str());
    EXPECT_STREQ("live", req.app.c_str());
    EXPECT_STREQ("1935", req.port.c_str());

    req.stream = "livestream";
    srs_discovery_tc_url("rtmp://s td.os srs.n et/li v e",
                         req.schema, req.host, req.vhost, req.app, req.stream, req.port, param);
    req.strip();
    EXPECT_STREQ("rtmp", req.schema.c_str());
    EXPECT_STREQ("std.ossrs.net", req.host.c_str());
    EXPECT_STREQ("std.ossrs.net", req.vhost.c_str());
    EXPECT_STREQ("live", req.app.c_str());
    EXPECT_STREQ("1935", req.port.c_str());

    req.stream = "livestream";
    srs_discovery_tc_url("rtmp://s\ntd.o\rssrs.ne\nt/li\nve",
                         req.schema, req.host, req.vhost, req.app, req.stream, req.port, param);
    req.strip();
    EXPECT_STREQ("rtmp", req.schema.c_str());
    EXPECT_STREQ("std.ossrs.net", req.host.c_str());
    EXPECT_STREQ("std.ossrs.net", req.vhost.c_str());
    EXPECT_STREQ("live", req.app.c_str());
    EXPECT_STREQ("1935", req.port.c_str());

    req.stream = "livestream";
    srs_discovery_tc_url("rtmp://std.ossrs.net/live ",
                         req.schema, req.host, req.vhost, req.app, req.stream, req.port, param);
    req.strip();
    EXPECT_STREQ("rtmp", req.schema.c_str());
    EXPECT_STREQ("std.ossrs.net", req.host.c_str());
    EXPECT_STREQ("std.ossrs.net", req.vhost.c_str());
    EXPECT_STREQ("live", req.app.c_str());
    EXPECT_STREQ("1935", req.port.c_str());

    EXPECT_TRUE(NULL == req.args);
    SrsRequest req1;
    req1.args = SrsAmf0Any::object();
    req.update_auth(&req1);
    EXPECT_TRUE(NULL != req.args);
    EXPECT_TRUE(req1.args != req.args);
}

TEST(ProtocolRTMPTest, RTMPHandshakeBytes) {
    MockBufferIO bio;
    SrsHandshakeBytes bytes;

    char hs[3073];
    bio.in_buffer.append(hs, sizeof(hs));
    bio.in_buffer.append(hs, sizeof(hs));

    EXPECT_TRUE(ERROR_SUCCESS == bytes.read_c0c1(&bio));
    EXPECT_TRUE(bytes.c0c1 != NULL);

    EXPECT_TRUE(ERROR_SUCCESS == bytes.read_c2(&bio));
    EXPECT_TRUE(bytes.c2 != NULL);

    EXPECT_TRUE(ERROR_SUCCESS == bytes.read_s0s1s2(&bio));
    EXPECT_TRUE(bytes.s0s1s2 != NULL);
}

#endif

